1 /* 2 * Entity - Entity is an object-relational mapping tool for the D programming language. Referring to the design idea of JPA. 3 * 4 * Copyright (C) 2015-2018 Shanghai Putao Technology Co., Ltd 5 * 6 * Developer: HuntLabs.cn 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.entity.eql.EqlParse; 13 14 import hunt.entity.eql.EqlInfo; 15 import hunt.entity; 16 import hunt.entity.EntityMetaInfo; 17 import hunt.sql; 18 19 import hunt.logging; 20 import hunt.collection; 21 import hunt.math; 22 import hunt.Number; 23 import hunt.String; 24 import hunt.Integer; 25 import hunt.Long; 26 import hunt.Double; 27 import hunt.Float; 28 import hunt.Short; 29 import hunt.Byte; 30 import hunt.Boolean; 31 import hunt.database; 32 import hunt.Nullable; 33 34 import std.algorithm.sorting; 35 import std.format; 36 import std.regex; 37 import std.string; 38 39 void eql_throw(string type, string message) { 40 throw new Exception("[EQL PARSE EXCEPTION. " ~ type ~ "] " ~ message); 41 } 42 43 /** 44 * 45 */ 46 private class EqlSubstitutionContext { 47 // EqlObject[string] eqlObjs; 48 // The key is the name of a model. 49 EntityFieldInfo[string][string] tableFields; 50 51 string[string] modelTableMap; 52 string[string] aliasModelMap; 53 54 string getTableByModel(string name, string defaultValue) { 55 auto itemPtr = name in modelTableMap; 56 if(itemPtr is null) { 57 version (HUNT_ENTITY_DEBUG) warningf("Can't find the table name for a mode: %s", name); 58 return defaultValue; 59 } else { 60 return *itemPtr; 61 } 62 } 63 64 string getModelByAlias(string name, string defaultValue) { 65 auto itemPtr = name in aliasModelMap; 66 if(itemPtr is null) { 67 version (HUNT_ENTITY_DEBUG) warningf("Can't find the model name for an alias: %s", name); 68 return defaultValue; 69 } else { 70 return *itemPtr; 71 } 72 } 73 } 74 75 /** 76 * 77 */ 78 class EqlParse { 79 alias EntityField = EntityFieldInfo[string]; 80 private string _eql; 81 private string _parsedEql; 82 private string _dbtype; 83 private ExportTableAliasVisitor _aliasVistor; //Table and alias 84 private SchemaStatVisitor _schemaVistor; 85 private List!SQLStatement _stmtList; 86 private string[string] _clsNameToTbName; 87 88 private EntityField[string] _tableFields; //Class name and field name 89 private EqlObject[string] _eqlObj; 90 public string[string] _objType; 91 private Object[string] _joinConds; 92 93 private Object[int] _params; 94 private Object[string] _parameters; 95 96 private EntityMetaInfo _entityInfo; 97 private FormatOption _formatOption; 98 private string _nativeSql; 99 100 this(string eql, ref EntityMetaInfo entityInfo, string dbtype = "mysql") 101 { 102 _entityInfo = entityInfo; 103 _parsedEql = _eql = eql; 104 _dbtype = dbtype; 105 _aliasVistor = new ExportTableAliasVisitor(); 106 _schemaVistor = SQLUtils.createSchemaStatVisitor(_dbtype); 107 108 _formatOption = new FormatOption(true, true); 109 _formatOption.config(VisitorFeature.OutputQuotedIdentifier, true); 110 } 111 112 FormatOption formatOption() { 113 return _formatOption; 114 } 115 116 void formatOption(FormatOption value) { 117 _formatOption = value; 118 } 119 120 string getEql() 121 { 122 return _eql; 123 } 124 125 string getDBType() 126 { 127 return _dbtype; 128 } 129 130 void setParsedEql(string parsedEql) 131 { 132 _parsedEql = parsedEql; 133 } 134 135 string getParsedEql() 136 { 137 return _parsedEql; 138 } 139 140 public void parse() 141 { 142 try 143 { 144 // version(HUNT_DEBUG)logInfo("-----> :",_parsedEql); 145 _stmtList = SQLUtils.parseStatements(_parsedEql, _dbtype); 146 147 foreach (stmt; _stmtList) 148 { 149 stmt.accept(_aliasVistor); 150 stmt.accept(_schemaVistor); 151 } 152 153 if (_stmtList.size == 0) 154 eql_throw("Statement", " statement error : " ~ _parsedEql); 155 156 init(); 157 } 158 catch (Exception e) 159 { 160 throw e; 161 } 162 163 } 164 165 private void init() 166 { 167 version(HUNT_ENTITY_DEBUG) { 168 tracef("_objType: %s", _objType); 169 } 170 171 _nativeSql = ""; 172 Map!(string, SQLTableSource) aliasMap = _aliasVistor.getAliasMap(); 173 foreach (string objName, SQLTableSource v; aliasMap) 174 { 175 string clsName; 176 SQLExpr expr = (cast(SQLExprTableSource) v).getExpr(); 177 if (cast(SQLIdentifierExpr) expr !is null) 178 { 179 clsName = (cast(SQLIdentifierExpr) expr).getName(); 180 } 181 else if (cast(SQLPropertyExpr) expr !is null) 182 { 183 // clsName = (cast(SQLPropertyExpr)expr); 184 clsName = _objType.get(convertExprAlias(cast(SQLPropertyExpr) expr), null); 185 } else { 186 version(HUNT_ENTITY_DEBUG) { 187 warningf("Unhandled expression: %s", typeid(cast(Object)expr)); 188 } 189 } 190 191 if(clsName.empty() || objName.empty()) { 192 version(HUNT_ENTITY_DEBUG) { 193 warningf("clsName: %s, objName: %s", clsName, objName); 194 } 195 continue; 196 } 197 198 auto obj = new EqlObject(objName, clsName); 199 _eqlObj[objName] = obj; 200 } 201 202 version (HUNT_ENTITY_DEBUG) { 203 trace(_clsNameToTbName); 204 } 205 206 foreach (string objName, EqlObject obj; _eqlObj) 207 { 208 string className = obj.className(); 209 if(className.empty()) { 210 warningf("className is empty for %s", objName); 211 continue; 212 } 213 // assert(!className.empty()); 214 215 string tableName = _clsNameToTbName.get(className, null); 216 if (tableName.empty()) { 217 eql_throw(className, "table is not found"); 218 } 219 obj.setTableName(tableName); 220 } 221 222 // logDebug("aliasMap : %s".format(aliasMap)); 223 224 // logDebug("cls name : %s".format(_clsNameToTbName)); 225 226 // logDebug("EQL OBJS : %s".format(_eqlObj)); 227 228 // logDebug("EQL Conds : %s".format(_joinConds)); 229 230 // logDebug("EQL objType : %s".format(_objType)); 231 232 if (cast(SQLSelectStatement)(_stmtList.get(0)) !is null) 233 { 234 // logDebug("EQL do_select_parse"); 235 doSelectParse(); 236 } 237 else if (cast(SQLUpdateStatement)(_stmtList.get(0)) !is null) 238 { 239 // logDebug("EQL do_update_parse"); 240 doUpdateParse(); 241 } 242 else if (cast(SQLDeleteStatement)(_stmtList.get(0)) !is null) 243 { 244 // logDebug("EQL do_delete_parse"); 245 doDeleteParse(); 246 } 247 else if (cast(SQLInsertStatement)(_stmtList.get(0)) !is null) 248 { 249 version (HUNT_ENTITY_DEBUG_MORE) 250 logDebug("EQL do_insert_parse"); 251 doInsertParse(); 252 } 253 else 254 { 255 eql_throw("Statement", 256 " unknown sql statement : " ~ typeid(cast(Object)(_stmtList.get(0))).toString); 257 } 258 259 // logDebug("init eql : %s".format(_parsedEql)); 260 } 261 262 private void doSelectParse() 263 { 264 auto queryBlock = (cast(SQLSelectStatement)(_stmtList.get(0))).getSelect().getQueryBlock(); 265 auto select_copy = queryBlock.clone(); 266 select_copy.getSelectList().clear(); 267 /// select item 268 foreach (selectItem; queryBlock.getSelectList()) 269 { 270 auto expr = selectItem.getExpr(); 271 272 Object oo = cast(Object)expr; 273 // version(HUNT_DEBUG) infof("Expr: %s, item: %s", typeid(oo).name, SQLUtils.toSQLString(selectItem)); 274 version(HUNT_ENTITY_DEBUG) infof("Expr: %s", typeid(oo).name); 275 276 if (cast(SQLIdentifierExpr) expr !is null) 277 { 278 auto eqlObj = _eqlObj.get((cast(SQLIdentifierExpr) expr).getName(), null); 279 if (eqlObj !is null) 280 { 281 auto clsName = eqlObj.className(); 282 EntityFieldInfo[string] fields = _tableFields.get(clsName, null); 283 284 if (fields !is null) 285 { 286 foreach (string classMember, EntityFieldInfo fieldInfo; fields) 287 { 288 if(fieldInfo.isAggregateType()) { 289 // ignore all the aggregative members; 290 version(HUNT_DEBUG) { 291 infof("Aggregative member ignored: %s", classMember); 292 } 293 294 continue; 295 } 296 297 if (!(clsName ~ "." ~ classMember in _objType)) /// ordinary member 298 { 299 string columnAlias = selectItem.getAlias(); 300 301 version(HUNT_ENTITY_DEBUG) { 302 tracef("columnAlias: [%s], SelectColumn: [%s], fullColumn: [%s]", 303 columnAlias, fieldInfo.getSelectColumn(), fieldInfo.getFullColumn()); 304 } 305 306 // SQLIdentifierExpr identifierExpr = new SQLIdentifierExpr(fieldInfo.getFullColumn()); 307 308 SQLIdentifierExpr identifierExpr = new SQLIdentifierExpr(columnAlias.empty() 309 ? fieldInfo.getSelectColumn() 310 : fieldInfo.getFullColumn()); 311 312 select_copy.addSelectItem(identifierExpr, columnAlias); 313 // logDebug("sql replace : (%s ,%s) ".format(clsName ~ "." ~ classMember,clsName ~ "." ~ fieldInfo.getSelectColumn())); 314 } 315 } 316 } 317 } 318 } 319 else if (cast(SQLPropertyExpr) expr !is null) 320 { 321 auto eqlObj = _eqlObj.get((cast(SQLPropertyExpr) expr).getOwnernName(), null); 322 auto currentFieldName = (cast(SQLPropertyExpr) expr).getName(); 323 if (eqlObj !is null) 324 { 325 bool isHandled = false; 326 auto fields = _tableFields.get(eqlObj.className(), null); 327 if (fields !is null) 328 { 329 foreach (string classMember, EntityFieldInfo fieldInfo; fields) { 330 string columnName = fieldInfo.getColumnName(); 331 version(HUNT_ENTITY_DEBUG_MORE) { 332 tracef("classMember: %s, columnName: %s, currentField: %s", 333 classMember, columnName, currentFieldName); 334 } 335 isHandled = classMember == currentFieldName || columnName == currentFieldName; 336 if (isHandled) 337 { 338 select_copy.addSelectItem(new SQLIdentifierExpr(selectItem.getAlias() is null 339 ? fieldInfo.getSelectColumn() 340 : fieldInfo.getFullColumn()), selectItem.getAlias()); 341 break; 342 } 343 // logDebug("sql replace : (%s ,%s) ".format(k ~ "." ~ classMember,k ~ "." ~ fieldInfo.getColumnName())); 344 } 345 } 346 347 if(!isHandled) { 348 string msg = format("Found a undefined memeber [%s] in class [%s]", 349 currentFieldName, eqlObj.className()); 350 warningf(msg); 351 352 // TODO: Tasks pending completion -@zhangxueping at 2020-10-20T14:32:17+08:00 353 // 354 // throw new EntityException(msg); 355 } 356 } 357 else 358 { 359 eql_throw("Statement", 360 " undefined sql object '%s' in '%s': ".format((cast(SQLPropertyExpr) expr).getOwnernName(),SQLUtils.toSQLString(expr))); 361 } 362 } 363 else if (cast(SQLAggregateExpr) expr !is null) 364 { 365 SQLAggregateExpr aggreExpr = cast(SQLAggregateExpr) expr; 366 List!SQLExpr newArgs = new ArrayList!SQLExpr(); 367 foreach (subExpr; aggreExpr.getArguments()) 368 { 369 // version(HUNT_ENTITY_DEBUG_MORE) { 370 // tracef("arg expr : %s, arg string : %s", 371 // typeid(cast(Object)subExpr).name, SQLUtils.toSQLString(subExpr)); 372 // } 373 374 if (cast(SQLIdentifierExpr) subExpr !is null) 375 { 376 newArgs.add(subExpr); 377 } 378 else if (cast(SQLPropertyExpr) subExpr !is null) 379 { 380 SQLPropertyExpr pExpr = cast(SQLPropertyExpr) subExpr; 381 auto eqlObj = _eqlObj.get(pExpr.getOwnernName(), null); 382 auto currentFieldName = (cast(SQLPropertyExpr) subExpr).getName(); 383 if (eqlObj !is null) 384 { 385 bool isHandled = false; 386 auto fields = _tableFields.get(eqlObj.className(), null); 387 if (fields !is null) 388 { 389 foreach (string classMember, EntityFieldInfo fieldInfo; fields) 390 { 391 string columnName = fieldInfo.getColumnName(); 392 393 version(HUNT_ENTITY_DEBUG_MORE) { 394 tracef("classMember: %s, columnName: %s, currentField: %s", 395 classMember, columnName, currentFieldName); 396 } 397 398 isHandled = classMember == currentFieldName || columnName == currentFieldName; 399 if (isHandled) 400 { 401 newArgs.add(new SQLPropertyExpr(eqlObj.tableName(), 402 fieldInfo.getColumnName())); 403 break; 404 } 405 } 406 } 407 408 if(!isHandled) { 409 string msg = format("Found a undefined memeber [%s] in class [%s]", 410 currentFieldName, eqlObj.className()); 411 warningf(msg); 412 413 // TODO: Tasks pending completion -@zhangxueping at 2020-10-20T14:32:17+08:00 414 // 415 // throw new EntityException(msg); 416 } 417 } 418 } 419 else 420 { 421 newArgs.add(subExpr); 422 } 423 } 424 aggreExpr.getArguments().clear(); 425 aggreExpr.getArguments().addAll(newArgs); 426 select_copy.addSelectItem(aggreExpr,selectItem.getAlias()); 427 } 428 else 429 { 430 version(HUNT_ENTITY_DEBUG_MORE) { 431 auto o = cast(Object)expr; 432 warningf("Expr: %s, item: %s", typeid(o).name, SQLUtils.toSQLString(selectItem)); 433 } 434 select_copy.addSelectItem(selectItem); 435 } 436 } 437 438 ///from 439 auto fromExpr = select_copy.getFrom(); 440 string[string] aliasModelMap; 441 442 SQLTableSource tableSource = cast(SQLTableSource)queryBlock.getFrom(); 443 SQLJoinTableSource joinTableSource = cast(SQLJoinTableSource)tableSource; 444 if(joinTableSource !is null) { 445 SQLExprTableSource exprTableSource = cast(SQLExprTableSource)joinTableSource.getLeft(); 446 if(exprTableSource !is null) { 447 SQLIdentifierExpr identifierExpr = cast(SQLIdentifierExpr)exprTableSource.getExpr(); 448 string tableAlias = exprTableSource.getAlias(); 449 450 if(!tableAlias.empty()) { 451 aliasModelMap[tableAlias] = identifierExpr.getName(); 452 } 453 } 454 455 exprTableSource = cast(SQLExprTableSource)joinTableSource.getRight(); 456 if(exprTableSource !is null) { 457 string tableAlias = exprTableSource.getAlias(); 458 string realName; 459 460 SQLIdentifierExpr identifierExpr = cast(SQLIdentifierExpr)exprTableSource.getExpr(); 461 if(identifierExpr !is null) { 462 realName = identifierExpr.getName(); 463 } 464 465 SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr)exprTableSource.getExpr(); 466 if(propertyExpr !is null) { 467 realName = propertyExpr.getName(); 468 } 469 470 if(realName.empty()) { 471 warningf("The actual type: %s", typeid(cast(Object)identifierExpr)); 472 } else if(!tableAlias.empty()) { 473 aliasModelMap[tableAlias] = realName; 474 } 475 } 476 } else { 477 SQLExprTableSource exprTableSource = cast(SQLExprTableSource)tableSource; 478 if(exprTableSource !is null) { 479 SQLIdentifierExpr identifierExpr = cast(SQLIdentifierExpr)exprTableSource.getExpr(); 480 string tableAlias = tableSource.getAlias(); 481 482 if(!tableAlias.empty()) { 483 aliasModelMap[tableAlias] = identifierExpr.getName(); 484 } 485 } else { 486 warningf("Can't handle table source: %s", typeid(cast(Object)tableSource)); 487 } 488 } 489 490 version(HUNT_ENTITY_DEBUG) { 491 warning(aliasModelMap); 492 } 493 494 parseFromTable(fromExpr); 495 496 497 ///where 498 auto whereCond = select_copy.getWhere(); 499 if (whereCond !is null) { 500 EqlSubstitutionContext context = new EqlSubstitutionContext(); 501 context.modelTableMap = _clsNameToTbName; 502 context.aliasModelMap = aliasModelMap; 503 context.tableFields = _tableFields; 504 // context.eqlObjs = _eqlObj; 505 506 // substituteInExpress(whereCond, context); 507 508 // FIXME: Needing refactor or cleanup -@zhangxueping at 2020-09-21T14:59:49+08:00 509 // Remove this block below. 510 511 string where = SQLUtils.toSQLString(whereCond); 512 version (HUNT_ENTITY_DEBUG) warning(where); 513 where = convertAttrExpr(where); 514 version (HUNT_ENTITY_DEBUG) trace(where); 515 SQLExpr newExpr = SQLUtils.toSQLExpr(where); 516 substituteInExpress(newExpr, context); 517 select_copy.setWhere(newExpr); 518 } 519 520 ///order by 521 auto orderBy = select_copy.getOrderBy(); 522 if (orderBy !is null) 523 { 524 version (HUNT_ENTITY_DEBUG) infof("Parsing the orderBy clause."); 525 foreach (item; orderBy.getItems) 526 { 527 auto exprStr = SQLUtils.toSQLString(item.getExpr(), _dbtype); 528 // version (HUNT_ENTITY_DEBUG_MORE) 529 // logDebug("order item : %s".format(exprStr)); 530 item.replace(item.getExpr(), SQLUtils.toSQLExpr(convertAttrExpr(exprStr), _dbtype)); 531 } 532 } 533 // else 534 // { 535 // version (HUNT_ENTITY_DEBUG_MORE) 536 // logDebug("order by item is null"); 537 // } 538 539 /// group by 540 auto groupBy = select_copy.getGroupBy(); 541 if (groupBy !is null) 542 { 543 version (HUNT_ENTITY_DEBUG) infof("Parsing the groupBy clause."); 544 groupBy.getItems().clear(); 545 foreach (item; queryBlock.getGroupBy().getItems()) 546 { 547 // logDebug("group item : %s".format(SQLUtils.toSQLString(item))); 548 groupBy.addItem(SQLUtils.toSQLExpr(convertAttrExpr(SQLUtils.toSQLString(item)))); 549 } 550 auto having = groupBy.getHaving(); 551 if (having !is null) 552 { 553 groupBy.setHaving(SQLUtils.toSQLExpr( 554 convertAttrExpr(SQLUtils.toSQLString(having)))); 555 } 556 select_copy.setGroupBy(groupBy); 557 } 558 559 version(HUNT_ENTITY_DEBUG) info("The parsing done. Now, converting it to native SQL..."); 560 _parsedEql = SQLUtils.toSQLString(select_copy, _dbtype); 561 version(HUNT_ENTITY_DEBUG) warning(_parsedEql); 562 563 } 564 565 private void doUpdateParse() 566 { 567 SQLUpdateStatement updateBlock = cast(SQLUpdateStatement)(_stmtList.get(0)); 568 /// update item 569 foreach (SQLUpdateSetItem updateItem; updateBlock.getItems()) 570 { 571 version(HUNT_ENTITY_DEBUG) 572 { 573 tracef("Update item (name: %s, value: %s)", SQLUtils.toSQLString(updateItem.getColumn()), 574 SQLUtils.toSQLString(updateItem.getValue)); 575 } 576 SQLExpr expr = updateItem.getColumn(); 577 578 if (cast(SQLIdentifierExpr) expr !is null) { 579 warning("Do nothing"); 580 } 581 582 if (cast(SQLPropertyExpr) expr !is null) 583 { 584 EqlObject eqlObj = _eqlObj.get((cast(SQLPropertyExpr) expr).getOwnernName(), null); 585 string currentFieldName = (cast(SQLPropertyExpr) expr).getName(); 586 if (eqlObj !is null) 587 { 588 bool isHandled = false; 589 EntityField fields = _tableFields.get(eqlObj.className(), null); 590 if (fields !is null) 591 { 592 foreach (string classMember, EntityFieldInfo fieldInfo; fields) { 593 if(fieldInfo.isAggregateType()) { 594 // ignore all the aggregative members; 595 version(HUNT_DEBUG) { 596 infof("Aggregative member ignored: %s", classMember); 597 } 598 599 continue; 600 } 601 string columnName = fieldInfo.getColumnName(); 602 603 version(HUNT_ENTITY_DEBUG_MORE) { 604 tracef("classMember: %s, columnName: %s, currentField: %s", 605 classMember, columnName, currentFieldName); 606 } 607 608 isHandled = classMember == currentFieldName || columnName == currentFieldName; 609 if (isHandled) { 610 if (_dbtype == DBType.POSTGRESQL.name) { 611 // PostgreSQL 612 // https://www.postgresql.org/docs/9.1/sql-update.html 613 updateItem.setColumn(new SQLIdentifierExpr(columnName)); 614 // updateItem.setColumn(new SQLPropertyExpr(eqlObj.tableName(), 615 // fieldInfo.getColumnName())); 616 } else { 617 updateItem.setColumn(new SQLPropertyExpr(eqlObj.tableName(), columnName)); 618 } 619 620 break; 621 } 622 } 623 } 624 625 if(!isHandled) { 626 string msg = format("Found a undefined memeber [%s] in class [%s]", 627 currentFieldName, eqlObj.className()); 628 warningf(msg); 629 630 // TODO: Tasks pending completion -@zhangxueping at 2020-10-20T14:32:17+08:00 631 // 632 // throw new EntityException(msg); 633 } 634 } 635 else 636 { 637 eql_throw("Statement", 638 " undefined sql object '%s' in '%s': ".format((cast(SQLPropertyExpr) expr).getOwnernName(), 639 SQLUtils.toSQLString(expr))); 640 } 641 } 642 643 auto valueExpr = updateItem.getValue(); 644 if (cast(SQLPropertyExpr) valueExpr !is null) 645 { 646 auto eqlObj = _eqlObj.get((cast(SQLPropertyExpr) valueExpr).getOwnernName(), null); 647 string currentFieldName = (cast(SQLPropertyExpr) valueExpr).getName(); 648 if (eqlObj !is null) 649 { 650 bool isHandled = false; 651 EntityField fields = _tableFields.get(eqlObj.className(), null); 652 if (fields !is null) 653 { 654 foreach (string classMember, EntityFieldInfo fieldInfo; fields) 655 { 656 string columnName = fieldInfo.getColumnName(); 657 658 version(HUNT_ENTITY_DEBUG_MORE) { 659 tracef("classMember: %s, columnName: %s, currentField: %s", 660 classMember, columnName, currentFieldName); 661 } 662 663 isHandled = classMember == currentFieldName || columnName == currentFieldName; 664 if (isHandled) 665 { 666 updateItem.setValue(new SQLPropertyExpr(eqlObj.tableName(), 667 columnName)); 668 break; 669 } 670 // tracef("sql replace : (%s ,%s) ", classMember, fieldInfo.getColumnName()); 671 } 672 } 673 674 if(!isHandled) { 675 string msg = format("Found a undefined memeber [%s] in class [%s]", 676 currentFieldName, eqlObj.className()); 677 warningf(msg); 678 679 // TODO: Tasks pending completion -@zhangxueping at 2020-10-20T14:32:17+08:00 680 // 681 // throw new EntityException(msg); 682 } 683 } 684 } 685 } 686 687 ///from 688 auto fromExpr = updateBlock.getTableSource(); 689 // logDebug("update From : %s".format(SQLUtils.toSQLString(fromExpr))); 690 parseFromTable(fromExpr); 691 692 ///where 693 SQLExpr whereCond = updateBlock.getWhere(); 694 if (whereCond !is null) 695 { 696 string where = SQLUtils.toSQLString(whereCond); 697 where = convertAttrExpr(where); 698 updateBlock.setWhere(SQLUtils.toSQLExpr(where)); 699 } 700 701 version(HUNT_ENTITY_DEBUG) info("The parsing done. Now, converting it to native SQL..."); 702 _parsedEql = SQLUtils.toSQLString(updateBlock, _dbtype); 703 version (HUNT_ENTITY_DEBUG) { 704 warning(_parsedEql); 705 } 706 } 707 708 private void doDeleteParse() 709 { 710 auto delBlock = cast(SQLDeleteStatement)(_stmtList.get(0)); 711 712 ///from 713 auto fromExpr = delBlock.getTableSource(); 714 // logDebug("delete From : %s".format(SQLUtils.toSQLString(fromExpr))); 715 716 parseFromTable(fromExpr); 717 718 ///where 719 auto whereCond = delBlock.getWhere(); 720 if (whereCond !is null) 721 { 722 auto where = SQLUtils.toSQLString(whereCond); 723 where = convertAttrExpr(where); 724 delBlock.setWhere(SQLUtils.toSQLExpr(where)); 725 } 726 727 _parsedEql = SQLUtils.toSQLString(delBlock, _dbtype); 728 } 729 730 private void doInsertParse() 731 { 732 SQLInsertStatement insertBlock = cast(SQLInsertStatement)(_stmtList.get(0)); 733 734 List!SQLExpr newColumns = new ArrayList!SQLExpr(); 735 736 /// insert item 737 foreach (expr; insertBlock.getColumns()) 738 { 739 version(HUNT_ENTITY_DEBUG_MORE) 740 trace("insert item :", SQLUtils.toSQLString(expr)); 741 if (cast(SQLIdentifierExpr) expr !is null) 742 { 743 newColumns.add(expr); 744 } 745 if (cast(SQLPropertyExpr) expr !is null) 746 { 747 SQLPropertyExpr pExpr = cast(SQLPropertyExpr) expr; 748 auto eqlObj = _eqlObj.get(pExpr.getOwnernName(), null); 749 string currentFieldName = (cast(SQLPropertyExpr) expr).getName(); 750 if (eqlObj !is null) 751 { 752 bool isHandled = false; 753 auto fields = _tableFields.get(eqlObj.className(), null); 754 if (fields !is null) 755 { 756 foreach (classMember, fieldInfo; fields) 757 { 758 string columnName = fieldInfo.getColumnName(); 759 760 version(HUNT_ENTITY_DEBUG_MORE) { 761 tracef("classMember: %s, columnName: %s, currentField: %s", 762 classMember, columnName, currentFieldName); 763 } 764 765 isHandled = classMember == currentFieldName || columnName == currentFieldName; 766 767 if (isHandled) 768 { 769 newColumns.add(new SQLIdentifierExpr(fieldInfo.getColumnName())); 770 break; 771 } 772 } 773 774 if(!isHandled) { 775 string msg = format("Found a undefined memeber [%s] in class [%s]", 776 currentFieldName, eqlObj.className()); 777 warningf(msg); 778 779 // TODO: Tasks pending completion -@zhangxueping at 2020-10-20T14:32:17+08:00 780 // 781 // throw new EntityException(msg); 782 } 783 } 784 } 785 else 786 { 787 eql_throw("Statement", 788 " undefined sql object '%s' in '%s': ".format(pExpr.getOwnernName(),SQLUtils.toSQLString(pExpr))); 789 } 790 } 791 insertBlock.getColumns().clear(); 792 insertBlock.getColumns().addAll(newColumns); 793 794 // auto valueExpr = updateItem.getValue(); 795 // if (cast(SQLPropertyExpr) valueExpr !is null) 796 // { 797 // auto eqlObj = _eqlObj.get((cast(SQLPropertyExpr) valueExpr).getOwnernName(), null); 798 // auto clsFieldName = (cast(SQLPropertyExpr) valueExpr).getName(); 799 // if (eqlObj !is null) 800 // { 801 // auto fields = _tableFields.get(eqlObj.className(), null); 802 // if (fields !is null) 803 // { 804 // foreach (classMember, fieldInfo; fields) 805 // { 806 // if (classMember == clsFieldName) 807 // { 808 // updateItem.setValue(new SQLPropertyExpr(eqlObj.tableName(), 809 // fieldInfo.getColumnName())); 810 // break; 811 // } 812 // // logDebug("sql replace : (%s ,%s) ".format(k ~ "." ~ classMember,k ~ "." ~ fieldInfo.getColumnName())); 813 // } 814 // } 815 // } 816 // } 817 } 818 819 ///from 820 SQLExprTableSource fromExpr = insertBlock.getTableSource(); 821 // version (HUNT_DEBUG) 822 // logDebug("Insert into: %s".format(SQLUtils.toSQLString(fromExpr))); 823 parseFromTable(fromExpr); 824 825 _parsedEql = SQLUtils.toSQLString(insertBlock, _dbtype); 826 827 if(_dbtype == DBType.POSTGRESQL) { 828 string autoIncrementKey = _entityInfo.autoIncrementKey; 829 _parsedEql = _parsedEql.stripRight(";"); 830 if(!autoIncrementKey.empty()) { 831 _parsedEql ~= " RETURNING " ~ autoIncrementKey ~ ";"; 832 } 833 } 834 } 835 836 /// a.id --- > Class.id , a is instance of Class 837 private string convertExprAlias(SQLPropertyExpr expr) 838 { 839 string originStr = SQLUtils.toSQLString(expr); 840 auto objName = expr.getOwnernName(); 841 auto subPropertyName = expr.getName(); 842 auto aliasMap = _aliasVistor.getAliasMap(); 843 string clsName; 844 foreach (obj, v; aliasMap) 845 { 846 if (obj == objName) 847 { 848 auto exprTab = (cast(SQLExprTableSource) v).getExpr(); 849 if (cast(SQLIdentifierExpr) exprTab !is null) 850 { 851 expr.setOwner(exprTab); 852 } 853 else if (cast(SQLPropertyExpr) exprTab !is null) 854 { 855 expr.setOwner(SQLUtils.toSQLExpr( 856 convertExprAlias(cast(SQLPropertyExpr) exprTab))); 857 } 858 } 859 } 860 // logDebug("get last type : ( %s , %s )".format(originStr,SQLUtils.toSQLString(expr))); 861 return SQLUtils.toSQLString(expr); 862 } 863 864 /// a.id --> Table.col 865 private string convertAttrExpr(string attrExpr) 866 { 867 string res = attrExpr; 868 auto conds = matchAll(attrExpr, regex("([^\\(\\s]+)\\.([^\\s]+)")); 869 bool[string] handerFlag; 870 foreach (cond; conds) 871 { 872 string newCond = cond.captures[0]; 873 if (newCond in handerFlag) 874 continue; 875 else 876 handerFlag[newCond] = true; 877 878 string owner = cond.captures[1]; 879 auto eqlObj = _eqlObj.get(owner, null); 880 if (eqlObj !is null) 881 { 882 newCond = newCond.replace(owner ~ ".", eqlObj.tableName() ~ "."); 883 auto fields = _tableFields.get(eqlObj.className(), null); 884 if (fields !is null) 885 { 886 foreach (classMember, fieldInfo; fields) 887 { 888 if (classMember == cond.captures[2]) 889 newCond = newCond.replace("." ~ cond.captures[2], 890 "." ~ fieldInfo.getColumnName()); 891 892 } 893 } 894 } 895 res = res.replace(cond.captures[0], newCond); 896 } 897 return res; 898 } 899 900 /// remove alias & a.xx -- > Table 901 private void parseFromTable(SQLTableSource fromExpr) 902 { 903 version (HUNT_ENTITY_DEBUG) infof("Parsing the FROM clause. The type is: %s", typeid(cast(Object)fromExpr)); 904 if (fromExpr is null) 905 { 906 eql_throw("Table", "no found table"); 907 } 908 // logDebug(" From table : %s".format(SQLUtils.toSQLString(fromExpr))); 909 if (cast(SQLJoinTableSource) fromExpr !is null) 910 { 911 auto joinExpr = cast(SQLJoinTableSource) fromExpr; 912 auto rightExpr = cast(SQLExprTableSource)(joinExpr.getRight()); 913 914 auto defaultJoinCond = joinExpr.getCondition(); 915 if (defaultJoinCond is null) 916 { 917 // logDebug("join table no default condition"); 918 } 919 else 920 { 921 auto convertAttrStr = convertAttrExpr(SQLUtils.toSQLString(defaultJoinCond)); 922 // logDebug(" join Cond : %s , convert : %s ".format(SQLUtils.toSQLString(defaultJoinCond),convertAttrStr)); 923 joinExpr.setCondition(SQLUtils.toSQLExpr(convertAttrStr)); 924 } 925 926 if (cast(SQLJoinTableSource)(joinExpr.getLeft()) !is null) 927 { 928 auto subExpr = cast(SQLJoinTableSource)(joinExpr.getLeft()); 929 parseFromTable(subExpr); 930 } 931 else if (cast(SQLExprTableSource)(joinExpr.getLeft()) !is null) 932 { 933 auto leftExpr = cast(SQLExprTableSource)(joinExpr.getLeft()); 934 935 if (cast(SQLPropertyExpr)(leftExpr.getExpr()) !is null) 936 { 937 string convertStr = convertExprAlias(cast(SQLPropertyExpr)(leftExpr.getExpr())); 938 string clsName = _objType.get(convertStr, null); 939 if (clsName !is null) 940 { 941 auto tableName = _clsNameToTbName.get(clsName, null); 942 if (tableName !is null) 943 { 944 leftExpr.setExpr(tableName); 945 } 946 } 947 948 Object joinCond = _joinConds.get(convertStr, null); 949 version(HUNT_ENTITY_DEBUG) { 950 logDebugf("add cond (left): ( %s , %s ), convertStr: %s", clsName, joinCond, convertStr); 951 } 952 953 if (joinCond !is null) 954 { 955 joinExpr.setCondition(SQLUtils.toSQLExpr(joinCond.toString())); 956 } 957 } 958 else if (cast(SQLIdentifierExpr)(leftExpr.getExpr()) !is null) 959 { 960 auto clsName = (cast(SQLIdentifierExpr)(leftExpr.getExpr())).getName(); 961 auto tableName = _clsNameToTbName.get(clsName, null); 962 if (tableName !is null) 963 { 964 leftExpr.setExpr(tableName); 965 } 966 } 967 leftExpr.setAlias(""); 968 } 969 970 if (rightExpr is null) 971 return; 972 if (cast(SQLPropertyExpr)(rightExpr.getExpr()) !is null) 973 { 974 auto convertStr = convertExprAlias(cast(SQLPropertyExpr)(rightExpr.getExpr())); 975 auto clsName = _objType.get(convertStr, null); 976 if (clsName !is null) 977 { 978 auto tableName = _clsNameToTbName.get(clsName, null); 979 if (tableName !is null) 980 { 981 rightExpr.setExpr(tableName); 982 } 983 } 984 auto joinCond = _joinConds.get(convertStr, null); 985 warning(_joinConds); 986 version(HUNT_ENTITY_DEBUG) { 987 logDebugf("add cond (right) : ( %s , %s ), convertStr: %s", clsName, joinCond, convertStr); 988 } 989 990 if (joinCond !is null) 991 { 992 joinExpr.setCondition(SQLUtils.toSQLExpr(joinCond.toString())); 993 } 994 } 995 else if (cast(SQLIdentifierExpr)(rightExpr.getExpr()) !is null) 996 { 997 auto clsName = (cast(SQLIdentifierExpr)(rightExpr.getExpr())).getName(); 998 auto tableName = _clsNameToTbName.get(clsName, null); 999 if (tableName !is null) 1000 { 1001 rightExpr.setExpr(tableName); 1002 } 1003 } 1004 1005 rightExpr.setAlias(""); 1006 } 1007 else 1008 { 1009 auto expr = cast(SQLExprTableSource)(fromExpr); 1010 if (expr is null) 1011 return; 1012 if (cast(SQLPropertyExpr)(expr.getExpr()) !is null) 1013 { 1014 auto convertStr = convertExprAlias(cast(SQLPropertyExpr)(expr.getExpr())); 1015 auto clsName = _objType.get(convertStr, null); 1016 if (clsName !is null) 1017 { 1018 auto tableName = _clsNameToTbName.get(clsName, null); 1019 if (tableName !is null) 1020 { 1021 expr.setExpr(tableName); 1022 } 1023 } 1024 1025 } 1026 else if (cast(SQLIdentifierExpr)(expr.getExpr()) !is null) 1027 { 1028 auto clsName = (cast(SQLIdentifierExpr)(expr.getExpr())).getName(); 1029 auto tableName = _clsNameToTbName.get(clsName, null); 1030 if (tableName !is null) 1031 { 1032 expr.setExpr(tableName); 1033 } 1034 } 1035 expr.setAlias(""); 1036 } 1037 } 1038 1039 public void setParameter(R)(int idx, R param) 1040 { 1041 static if (is(R == int) || is(R == uint)) 1042 { 1043 _params[idx] = new Integer(param); 1044 } 1045 else static if (is(R == char)) 1046 { 1047 _params[idx] = new String(cast(string)[param]); 1048 } 1049 else static if (is(R == string)) 1050 { 1051 _params[idx] = new String(param); 1052 } 1053 else static if (is(R == byte[]) || is(R == ubyte[])) 1054 { 1055 _params[idx] = new Bytes(cast(byte[]) param); 1056 } 1057 else static if (is(R == bool)) 1058 { 1059 _params[idx] = new Boolean(param); 1060 } 1061 else static if (is(R == double)) 1062 { 1063 _params[idx] = new Double(param); 1064 } 1065 else static if (is(R == float)) 1066 { 1067 _params[idx] = new Float(param); 1068 } 1069 else static if (is(R == short) || is(R == ushort)) 1070 { 1071 _params[idx] = new Short(param); 1072 } 1073 else static if (is(R == long) || is(R == ulong)) 1074 { 1075 _params[idx] = new Long(param); 1076 } 1077 else static if (is(R == byte) || is(R == ubyte)) 1078 { 1079 _params[idx] = new Byte(param); 1080 } 1081 else static if (is(R == class)) 1082 { 1083 _params[idx] = param; 1084 } 1085 else 1086 { 1087 eql_throw("setParameter", "IllegalArgument not support : " ~ R.stringof); 1088 } 1089 } 1090 1091 public void setParameter(R)(string key, R param) 1092 { 1093 static if (is(R == int) || is(R == uint)) 1094 { 1095 _parameters[key] = new Integer(param); 1096 } 1097 else static if (is(R == char)) 1098 { 1099 _parameters[key] = new String(cast(string)[param]); 1100 } 1101 else static if (is(R == string)) 1102 { 1103 _parameters[key] = new String(param); 1104 } 1105 else static if (is(R == byte[]) || is(R == ubyte[])) 1106 { 1107 _parameters[key] = new Bytes(cast(byte[]) param); 1108 } 1109 // else static if (is(R == string) || is(R == char) || is(R == byte[])) 1110 // { 1111 // _parameters[key] = new String(param); 1112 // } 1113 else static if (is(R == bool)) 1114 { 1115 _parameters[key] = new Boolean(param); 1116 } 1117 else static if (is(R == double)) 1118 { 1119 _parameters[key] = new Double(param); 1120 } 1121 else static if (is(R == float)) 1122 { 1123 _parameters[key] = new Float(param); 1124 } 1125 else static if (is(R == short) || is(R == ushort)) 1126 { 1127 _parameters[key] = new Short(param); 1128 } 1129 else static if (is(R == long) || is(R == ulong)) 1130 { 1131 _parameters[key] = new Long(param); 1132 } 1133 else static if (is(R == byte) || is(R == ubyte)) 1134 { 1135 _parameters[key] = new Byte(param); 1136 } 1137 else static if (is(R == class)) 1138 { 1139 _parameters[key] = param; 1140 } 1141 else 1142 { 1143 eql_throw("setParameter", "IllegalArgument not support : " ~ R.stringof); 1144 } 1145 } 1146 1147 public void putClsTbName(string clsName, string tableName) 1148 { 1149 _clsNameToTbName[clsName] = tableName; 1150 } 1151 1152 public void putFields(string table, EntityField ef) 1153 { 1154 version(HUNT_ENTITY_DEBUG) { 1155 infof("table: %s", table); 1156 foreach (string classMember, EntityFieldInfo fieldInfo; ef) { 1157 tracef("classMember: %s, isAggregateType: %s, fullColumn: [%s]", 1158 classMember, fieldInfo.isAggregateType(), fieldInfo.getFullColumn()); 1159 } 1160 } 1161 _tableFields[table] = ef; 1162 } 1163 1164 public void putJoinCond(Object[string] conds) 1165 { 1166 foreach (k, v; conds) 1167 { 1168 _joinConds[k] = v; 1169 } 1170 } 1171 1172 public string getTableName(string clsName) 1173 { 1174 return _clsNameToTbName.get(clsName, null); 1175 } 1176 1177 public string getNativeSql() 1178 { 1179 if(!_nativeSql.empty()) 1180 return _nativeSql; 1181 1182 string sql = _parsedEql; 1183 1184 version (HUNT_ENTITY_DEBUG_MORE) 1185 logDebug("EQL params : ", _parameters); 1186 1187 foreach (k, v; _parameters) 1188 { 1189 auto re = regex(r":" ~ k ~ r"([^\w]*)", "g"); 1190 if (cast(String) v !is null || (cast(Nullable!string) v !is null)) 1191 { 1192 version (HUNT_ENTITY_DEBUG_MORE) 1193 logInfo("-----: ", v.toString); 1194 if (_dbtype == DBType.POSTGRESQL.name) 1195 sql = sql.replaceAll(re, quoteSqlString(v.toString(), "'") ~ "$1"); 1196 else 1197 sql = sql.replaceAll(re, quoteSqlString(v.toString()) ~ "$1"); 1198 } 1199 else 1200 { 1201 sql = sql.replaceAll(re, v.toString() ~ "$1"); 1202 } 1203 } 1204 1205 if (_params.length > 0) 1206 { 1207 auto keys = _params.keys; 1208 sort!("a < b")(keys); 1209 List!Object params = new ArrayList!Object(); 1210 foreach (e; keys) 1211 { 1212 params.add(_params[e]); 1213 } 1214 sql = SQLUtils.format(sql, _dbtype, params, _formatOption); 1215 // sql = SQLUtils.format(sql, _dbtype, params); 1216 } else { 1217 sql = SQLUtils.format(sql, _dbtype, _formatOption); 1218 // sql = SQLUtils.format(sql, _dbtype); 1219 } 1220 1221 // FIXME: Needing refactor or cleanup -@zhangxueping at 2019-10-09T14:41:55+08:00 1222 // why? 1223 // if (_dbtype == DBType.POSTGRESQL.name && _params.length == 0) { 1224 // sql = SQLUtils.format(sql, _dbtype, _formatOption); 1225 // warning(sql); 1226 // } 1227 1228 version(HUNT_ENTITY_DEBUG) infof("result sql : %s", sql); 1229 _nativeSql = sql; 1230 return sql; 1231 } 1232 1233 1234 // SQLInSubQueryExpr 1235 static void substitute(SQLInSubQueryExpr subQueryExpr, EqlSubstitutionContext context) { 1236 version (HUNT_ENTITY_DEBUG) tracef("Handling a SQLInSubQueryExpr"); 1237 1238 // in express 1239 SQLPropertyExpr expr = cast(SQLPropertyExpr)subQueryExpr.getExpr(); 1240 string ownerName = expr.getOwnernName(); 1241 auto itemPtr = ownerName in context.aliasModelMap; 1242 if(itemPtr !is null) { 1243 ownerName = *itemPtr; 1244 ownerName = context.modelTableMap.get(ownerName, ownerName); 1245 expr.setOwner(ownerName); 1246 } 1247 1248 // version (HUNT_ENTITY_DEBUG) warningf("ownerName: %s", ownerName); 1249 1250 // select clause 1251 substitute(subQueryExpr.getSubQuery(), context); 1252 1253 } 1254 1255 // SQLIdentifierExpr 1256 static void substitute(SQLIdentifierExpr expr, EqlSubstitutionContext context) { 1257 version (HUNT_ENTITY_DEBUG) tracef("Handling an SQLIdentifierExpr"); 1258 string className = expr.getName(); 1259 // version (HUNT_ENTITY_DEBUG) tracef("className: %s", className); 1260 1261 auto itemPtr = className in context.modelTableMap; 1262 if(itemPtr is null) { 1263 version (HUNT_ENTITY_DEBUG) warningf("No mapped model name found for class: %s", className); 1264 } else { 1265 expr.setName(*itemPtr); 1266 } 1267 } 1268 1269 // SQLPropertyExpr 1270 static void substitute(SQLPropertyExpr expr, EqlSubstitutionContext context) { 1271 version (HUNT_ENTITY_DEBUG) tracef("Handling an SQLPropertyExpr"); 1272 1273 string ownerName = expr.getOwnernName(); 1274 string fieldName = expr.getName(); 1275 1276 if(ownerName.empty()) { 1277 warningf("No owner found before [%s]", fieldName); 1278 return; 1279 } 1280 1281 version (HUNT_ENTITY_DEBUG) trace(context.tableFields.keys); 1282 1283 // owner 1284 string modelName = context.getModelByAlias(ownerName, ownerName); 1285 string tableName = context.getTableByModel(modelName, modelName); 1286 1287 if(tableName != ownerName) { 1288 expr.setOwner(tableName); 1289 } 1290 1291 version (HUNT_ENTITY_DEBUG) { 1292 tracef("ownerName, alias: %s, model: %s, table: %s", ownerName, modelName, tableName); 1293 } 1294 1295 // name 1296 EntityFieldInfo[string] fields = context.tableFields.get(modelName, null); 1297 foreach (string member, EntityFieldInfo fieldInfo; fields) { 1298 if(member == fieldName) { 1299 string columnName = fieldInfo.getColumnName(); 1300 version (HUNT_ENTITY_DEBUG_MORE) { 1301 tracef("The field's name is substituted from [%s] to [%s]", fieldName, columnName); 1302 } 1303 expr.setName(columnName); 1304 break; 1305 } 1306 } 1307 1308 // TODO: Tasks pending completion -@zhangxueping at 2020-09-21T11:41:18+08:00 1309 // a => * 1310 } 1311 1312 1313 // SQLBinaryOpExpr 1314 static void substitute(SQLBinaryOpExpr expr, EqlSubstitutionContext context) { 1315 version (HUNT_ENTITY_DEBUG) tracef("Handling an SQLBinaryOpExpr"); 1316 1317 // Left 1318 SQLExpr leftExpr = expr.getLeft(); 1319 substituteInExpress(leftExpr, context); 1320 1321 // Right 1322 SQLExpr rightExpr = expr.getRight(); 1323 substituteInExpress(rightExpr, context); 1324 } 1325 1326 static void substitute(SQLNumericLiteralExpr expr, EqlSubstitutionContext context) { 1327 version (HUNT_ENTITY_DEBUG) tracef("Handling an SQLNumericLiteralExpr"); 1328 // do nothing 1329 } 1330 1331 static void substitute(SQLTextLiteralExpr expr, EqlSubstitutionContext context) { 1332 version (HUNT_ENTITY_DEBUG) tracef("Handling an SQLTextLiteralExpr"); 1333 // do nothing 1334 } 1335 1336 static void substitute(SQLInListExpr expr, EqlSubstitutionContext context) { 1337 version (HUNT_ENTITY_DEBUG) tracef("Handling an SQLInListExpr"); 1338 SQLExpr sqlExpr = expr.getExpr(); 1339 1340 substituteInExpress(sqlExpr, context); 1341 1342 // 1343 List!SQLExpr targets = expr.getTargetList(); 1344 foreach(SQLExpr se; targets) { 1345 substituteInExpress(se, context); 1346 } 1347 } 1348 1349 static void substituteInExpress(SQLExpr sqlExpr, EqlSubstitutionContext context) { 1350 version (HUNT_ENTITY_DEBUG) infof("Handling an express: %s", typeid(cast(Object)sqlExpr)); 1351 1352 SQLIdentifierExpr identifierExpr = cast(SQLIdentifierExpr)sqlExpr; 1353 if(identifierExpr !is null) { 1354 substitute(identifierExpr, context); 1355 return; 1356 } 1357 1358 SQLPropertyExpr propertyExpr = cast(SQLPropertyExpr)sqlExpr; 1359 if(propertyExpr !is null) { 1360 substitute(propertyExpr, context); 1361 return; 1362 } 1363 1364 SQLInSubQueryExpr subQueryExpr = cast(SQLInSubQueryExpr)sqlExpr; 1365 if(subQueryExpr !is null) { 1366 substitute(subQueryExpr, context); 1367 return; 1368 } 1369 1370 SQLBinaryOpExpr opExpr = cast(SQLBinaryOpExpr)sqlExpr; 1371 if(opExpr !is null) { 1372 substitute(opExpr, context); 1373 return; 1374 } 1375 1376 SQLNumericLiteralExpr numberExpr = cast(SQLNumericLiteralExpr)sqlExpr; 1377 if(numberExpr !is null) { 1378 substitute(numberExpr, context); 1379 return; 1380 } 1381 1382 SQLTextLiteralExpr textExpr = cast(SQLTextLiteralExpr)sqlExpr; 1383 if(textExpr !is null) { 1384 substitute(textExpr, context); 1385 return; 1386 } 1387 1388 SQLInListExpr inListExpr = cast(SQLInListExpr)sqlExpr; 1389 if(inListExpr !is null) { 1390 substitute(inListExpr, context); 1391 return; 1392 } 1393 1394 warningf("A express can't be handled: %s", typeid(cast(Object)sqlExpr)); 1395 } 1396 1397 static void substitute(SQLSelect subSelect, EqlSubstitutionContext context) { 1398 SQLSelectQueryBlock queryBlock = cast(SQLSelectQueryBlock)subSelect.getQuery(); 1399 1400 // The FROM clause 1401 SQLExprTableSource fromExpr = cast(SQLExprTableSource)queryBlock.getFrom(); 1402 string tableAlias = fromExpr.getAlias(); 1403 if(!tableAlias.empty()) { 1404 fromExpr.setAlias(""); 1405 1406 SQLIdentifierExpr identifierExpr = cast(SQLIdentifierExpr)fromExpr.getExpr(); 1407 if(identifierExpr !is null) { 1408 version (HUNT_ENTITY_DEBUG) tracef("Removing the alias: %s", tableAlias); 1409 context.aliasModelMap[tableAlias] = identifierExpr.getName(); 1410 } 1411 } 1412 1413 SQLExpr sqlExpr = fromExpr.getExpr(); 1414 substituteInExpress(sqlExpr, context); 1415 1416 // The selected fields 1417 foreach (SQLSelectItem selectItem; queryBlock.getSelectList()) { 1418 SQLExpr expr = selectItem.getExpr(); 1419 substituteInExpress(expr, context); 1420 } 1421 1422 // where 1423 SQLExpr whereExpr = queryBlock.getWhere(); 1424 if(whereExpr !is null) { 1425 substituteInExpress(whereExpr, context); 1426 } 1427 } 1428 }