1 package org.apache.ojb.broker.accesslayer.sql; 2 3 17 18 import java.util.Collection ; 19 import java.util.Enumeration ; 20 import java.util.Map ; 21 22 import org.apache.commons.collections.map.ReferenceIdentityMap; 23 import org.apache.ojb.broker.metadata.ClassDescriptor; 24 import org.apache.ojb.broker.metadata.ProcedureDescriptor; 25 import org.apache.ojb.broker.platforms.Platform; 26 import org.apache.ojb.broker.query.BetweenCriteria; 27 import org.apache.ojb.broker.query.Criteria; 28 import org.apache.ojb.broker.query.ExistsCriteria; 29 import org.apache.ojb.broker.query.FieldCriteria; 30 import org.apache.ojb.broker.query.InCriteria; 31 import org.apache.ojb.broker.query.NullCriteria; 32 import org.apache.ojb.broker.query.Query; 33 import org.apache.ojb.broker.query.SelectionCriteria; 34 import org.apache.ojb.broker.query.SqlCriteria; 35 import org.apache.ojb.broker.util.logging.Logger; 36 import org.apache.ojb.broker.util.logging.LoggerFactory; 37 38 47 public class SqlGeneratorDefaultImpl implements SqlGenerator 48 { 49 private Logger logger = LoggerFactory.getLogger(SqlGeneratorDefaultImpl.class); 50 private Platform m_platform; 51 62 63 private Map sqlForClass = new ReferenceIdentityMap(ReferenceIdentityMap.WEAK, ReferenceIdentityMap.HARD); 64 65 public SqlGeneratorDefaultImpl(Platform platform) 66 { 67 this.m_platform = platform; 68 } 69 70 75 public SqlStatement getPreparedDeleteStatement(ClassDescriptor cld) 76 { 77 SqlForClass sfc = getSqlForClass(cld); 78 SqlStatement sql = sfc.getDeleteSql(); 79 if(sql == null) 80 { 81 ProcedureDescriptor pd = cld.getDeleteProcedure(); 82 83 if(pd == null) 84 { 85 sql = new SqlDeleteByPkStatement(cld, logger); 86 } 87 else 88 { 89 sql = new SqlProcedureStatement(pd, logger); 90 } 91 sfc.setDeleteSql(sql); 93 94 if(logger.isDebugEnabled()) 95 { 96 logger.debug("SQL:" + sql.getStatement()); 97 } 98 } 99 return sql; 100 } 101 102 108 public SqlStatement getPreparedInsertStatement(ClassDescriptor cld) 109 { 110 SqlStatement sql; 111 SqlForClass sfc = getSqlForClass(cld); 112 sql = sfc.getInsertSql(); 113 if(sql == null) 114 { 115 ProcedureDescriptor pd = cld.getInsertProcedure(); 116 117 if(pd == null) 118 { 119 sql = new SqlInsertStatement(cld, logger); 120 } 121 else 122 { 123 sql = new SqlProcedureStatement(pd, logger); 124 } 125 sfc.setInsertSql(sql); 127 128 if(logger.isDebugEnabled()) 129 { 130 logger.debug("SQL:" + sql.getStatement()); 131 } 132 } 133 return sql; 134 } 135 136 141 public SelectStatement getPreparedSelectByPkStatement(ClassDescriptor cld) 142 { 143 SelectStatement sql; 144 SqlForClass sfc = getSqlForClass(cld); 145 sql = sfc.getSelectByPKSql(); 146 if(sql == null) 147 { 148 sql = new SqlSelectByPkStatement(m_platform, cld, logger); 149 150 sfc.setSelectByPKSql(sql); 152 153 if(logger.isDebugEnabled()) 154 { 155 logger.debug("SQL:" + sql.getStatement()); 156 } 157 } 158 return sql; 159 } 160 161 public SqlStatement getPreparedExistsStatement(ClassDescriptor cld) 162 { 163 SqlStatement sql; 164 SqlForClass sfc = getSqlForClass(cld); 165 sql = sfc.getSelectExists(); 166 if(sql == null) 167 { 168 sql = new SqlExistStatement(cld, logger); 170 sfc.setSelectExists(sql); 172 if(logger.isDebugEnabled()) 173 { 174 logger.debug("SQL:" + sql.getStatement()); 175 } 176 } 177 return sql; 178 } 179 180 186 public SelectStatement getPreparedSelectStatement(Query query, ClassDescriptor cld) 187 { 188 SelectStatement sql = new SqlSelectStatement(m_platform, cld, query, logger); 189 if (logger.isDebugEnabled()) 190 { 191 logger.debug("SQL:" + sql.getStatement()); 192 } 193 return sql; 194 } 195 196 201 public SqlStatement getPreparedUpdateStatement(ClassDescriptor cld) 202 { 203 SqlForClass sfc = getSqlForClass(cld); 204 SqlStatement result = sfc.getUpdateSql(); 205 if(result == null) 206 { 207 ProcedureDescriptor pd = cld.getUpdateProcedure(); 208 209 if(pd == null) 210 { 211 result = new SqlUpdateStatement(cld, logger); 212 } 213 else 214 { 215 result = new SqlProcedureStatement(pd, logger); 216 } 217 sfc.setUpdateSql(result); 219 220 if(logger.isDebugEnabled()) 221 { 222 logger.debug("SQL:" + result.getStatement()); 223 } 224 } 225 return result; 226 } 227 228 235 public String getInsertMNStatement(String table, String [] pkColumns1, String [] pkColumns2) 236 { 237 SqlStatement sql; 238 String result; 239 240 String [] cols = new String [pkColumns1.length + pkColumns2.length]; 241 System.arraycopy(pkColumns1, 0, cols, 0, pkColumns1.length); 242 System.arraycopy(pkColumns2, 0, cols, pkColumns1.length, pkColumns2.length); 243 244 sql = new SqlInsertMNStatement(table, cols, logger); 245 result = sql.getStatement(); 246 247 if (logger.isDebugEnabled()) 248 { 249 logger.debug("SQL:" + result); 250 } 251 return result; 252 } 253 254 261 public String getSelectMNStatement(String table, String [] selectColumns, String [] columns) 262 { 263 SqlStatement sql; 264 String result; 265 266 sql = new SqlSelectMNStatement(table, selectColumns, columns, logger); 267 result = sql.getStatement(); 268 269 if (logger.isDebugEnabled()) 270 { 271 logger.debug("SQL:" + result); 272 } 273 return result; 274 } 275 276 283 public String getDeleteMNStatement(String table, String [] pkColumns1, String [] pkColumns2) 284 { 285 SqlStatement sql; 286 String result; 287 String [] cols; 288 289 if (pkColumns2 == null) 290 { 291 cols = pkColumns1; 292 } 293 else 294 { 295 cols = new String [pkColumns1.length + pkColumns2.length]; 296 System.arraycopy(pkColumns1, 0, cols, 0, pkColumns1.length); 297 System.arraycopy(pkColumns2, 0, cols, pkColumns1.length, pkColumns2.length); 298 } 299 300 sql = new SqlDeleteMNStatement(table, cols, logger); 301 result = sql.getStatement(); 302 303 if (logger.isDebugEnabled()) 304 { 305 logger.debug("SQL:" + result); 306 } 307 return result; 308 } 309 310 315 public SelectStatement getSelectStatementDep(Query query, ClassDescriptor cld) 316 { 317 return getPreparedSelectStatement(query, cld); 319 } 320 321 326 public String asSQLStatement(Criteria crit, ClassDescriptor cld) 327 { 328 Enumeration e = crit.getElements(); 329 StringBuffer statement = new StringBuffer (); 330 while (e.hasMoreElements()) 331 { 332 Object o = e.nextElement(); 333 if (o instanceof Criteria) 334 { 335 String addAtStart; 336 String addAtEnd; 337 Criteria pc = (Criteria) o; 338 if (pc.isEmbraced()) 340 { 341 addAtStart = " ("; 342 addAtEnd = ") "; 343 } 344 else 345 { 346 addAtStart = ""; 347 addAtEnd = ""; 348 } 349 350 switch (pc.getType()) 351 { 352 case (Criteria.OR) : 353 { 354 statement.append(" OR ").append(addAtStart); 355 statement.append(asSQLStatement(pc, cld)); 356 statement.append(addAtEnd); 357 break; 358 } 359 case (Criteria.AND) : 360 { 361 statement.insert(0, "( "); 362 statement.append(") "); 363 statement.append(" AND ").append(addAtStart); 364 statement.append(asSQLStatement(pc, cld)); 365 statement.append(addAtEnd); 366 break; 367 } 368 } 369 } 370 else 371 { 372 SelectionCriteria c = (SelectionCriteria) o; 373 if (statement.length() == 0) 374 { 375 statement.append(asSQLClause(c, cld)); 376 } 377 else 378 { 379 statement.insert(0, "("); 380 statement.append(") "); 381 statement.append(" AND "); 382 statement.append(asSQLClause(c, cld)); 383 } 384 } 385 } if (statement.length() == 0) 387 { 388 return null; 389 } 390 return statement.toString(); 391 } 392 393 399 protected String asSQLClause(SelectionCriteria c, ClassDescriptor cld) 400 { 401 if (c instanceof FieldCriteria) 402 return toSQLClause((FieldCriteria) c, cld); 403 404 if (c instanceof NullCriteria) 405 return toSQLClause((NullCriteria) c); 406 407 if (c instanceof BetweenCriteria) 408 return toSQLClause((BetweenCriteria) c, cld); 409 410 if (c instanceof InCriteria) 411 return toSQLClause((InCriteria) c); 412 413 if (c instanceof SqlCriteria) 414 return toSQLClause((SqlCriteria) c); 415 416 if (c instanceof ExistsCriteria) 417 return toSQLClause((ExistsCriteria) c, cld); 418 419 return toSQLClause(c, cld); 420 } 421 422 private String toSqlClause(Object attributeOrQuery, ClassDescriptor cld) 423 { 424 String result; 425 426 if (attributeOrQuery instanceof Query) 427 { 428 Query q = (Query) attributeOrQuery; 429 result = getPreparedSelectStatement(q, cld.getRepository().getDescriptorFor(q.getSearchClass())) 430 .getStatement(); 431 } 432 else 433 { 434 result = (String )attributeOrQuery; 435 } 436 437 return result; 438 } 439 440 445 private String toSQLClause(NullCriteria c) 446 { 447 String colName = (String )c.getAttribute(); 448 return colName + c.getClause(); 449 } 450 451 457 private String toSQLClause(FieldCriteria c, ClassDescriptor cld) 458 { 459 String colName = toSqlClause(c.getAttribute(), cld); 460 return colName + c.getClause() + c.getValue(); 461 } 462 463 469 private String toSQLClause(BetweenCriteria c, ClassDescriptor cld) 470 { 471 String colName = toSqlClause(c.getAttribute(), cld); 472 return colName + c.getClause() + " ? AND ? "; 473 } 474 475 480 private String toSQLClause(InCriteria c) 481 { 482 StringBuffer buf = new StringBuffer (); 483 Collection values = (Collection ) c.getValue(); 484 int size = values.size(); 485 486 buf.append(c.getAttribute()); 487 buf.append(c.getClause()); 488 buf.append("("); 489 for (int i = 0; i < size - 1; i++) 490 { 491 buf.append("?,"); 492 } 493 buf.append("?)"); 494 return buf.toString(); 495 } 496 497 503 private String toSQLClause(SelectionCriteria c, ClassDescriptor cld) 504 { 505 String colName = toSqlClause(c.getAttribute(), cld); 506 return colName + c.getClause() + " ? "; 507 } 508 509 514 private String toSQLClause(SqlCriteria c) 515 { 516 return c.getClause(); 517 } 518 519 525 private String toSQLClause(ExistsCriteria c, ClassDescriptor cld) 526 { 527 StringBuffer buf = new StringBuffer (); 528 Query subQuery = (Query) c.getValue(); 529 530 buf.append(c.getClause()); 531 buf.append(" ("); 532 533 if (cld != null) 535 { 536 buf.append( 537 getPreparedSelectStatement( 538 subQuery, 539 cld.getRepository().getDescriptorFor(subQuery.getSearchClass()))); 540 541 } 543 else 544 { 545 buf.append(subQuery); 546 } 547 548 buf.append(")"); 549 return buf.toString(); 550 } 551 552 557 public SqlStatement getPreparedDeleteStatement(Query query, ClassDescriptor cld) 558 { 559 return new SqlDeleteByQuery(m_platform, cld, query, logger); 560 } 561 562 565 public Platform getPlatform() 566 { 567 return m_platform; 568 } 569 570 577 protected SqlForClass getSqlForClass(ClassDescriptor cld) 578 { 579 SqlForClass result = (SqlForClass) sqlForClass.get(cld); 580 if(result == null) 581 { 582 result = newInstanceSqlForClass(); 583 sqlForClass.put(cld, result); 584 } 585 return result; 586 } 587 588 595 protected SqlForClass newInstanceSqlForClass() 596 { 597 return new SqlForClass(); 598 } 599 600 604 608 public static class SqlForClass 609 { 610 private SqlStatement deleteSql; 611 private SqlStatement insertSql; 612 private SqlStatement updateSql; 613 private SelectStatement selectByPKSql; 614 private SqlStatement selectExists; 615 616 public SqlStatement getDeleteSql() 617 { 618 return deleteSql; 619 } 620 621 public void setDeleteSql(SqlStatement deleteSql) 622 { 623 this.deleteSql = deleteSql; 624 } 625 626 public SqlStatement getInsertSql() 627 { 628 return insertSql; 629 } 630 631 public void setInsertSql(SqlStatement insertSql) 632 { 633 this.insertSql = insertSql; 634 } 635 636 public SqlStatement getUpdateSql() 637 { 638 return updateSql; 639 } 640 641 public void setUpdateSql(SqlStatement updateSql) 642 { 643 this.updateSql = updateSql; 644 } 645 646 public SelectStatement getSelectByPKSql() 647 { 648 return selectByPKSql; 649 } 650 651 public void setSelectByPKSql(SelectStatement selectByPKSql) 652 { 653 this.selectByPKSql = selectByPKSql; 654 } 655 656 public SqlStatement getSelectExists() 657 { 658 return selectExists; 659 } 660 661 public void setSelectExists(SqlStatement selectExists) 662 { 663 this.selectExists = selectExists; 664 } 665 } 666 667 } 668 | Popular Tags |