1 27 package com.genimen.djeneric.repository.rdbms; 28 29 import java.math.BigDecimal ; 30 import java.sql.Connection ; 31 import java.sql.ResultSet ; 32 import java.sql.SQLException ; 33 import java.sql.Types ; 34 import java.util.HashMap ; 35 import java.util.Iterator ; 36 37 import com.genimen.djeneric.language.Messages; 38 import com.genimen.djeneric.repository.DjContext; 39 import com.genimen.djeneric.repository.DjCursor; 40 import com.genimen.djeneric.repository.DjDomain; 41 import com.genimen.djeneric.repository.DjExtent; 42 import com.genimen.djeneric.repository.DjList; 43 import com.genimen.djeneric.repository.DjObject; 44 import com.genimen.djeneric.repository.DjObjectMatcher; 45 import com.genimen.djeneric.repository.DjOql; 46 import com.genimen.djeneric.repository.DjPersistenceManager; 47 import com.genimen.djeneric.repository.DjProperty; 48 import com.genimen.djeneric.repository.DjQueryByExample; 49 import com.genimen.djeneric.repository.DjSession; 50 import com.genimen.djeneric.repository.exceptions.DjenericException; 51 import com.genimen.djeneric.repository.exceptions.ObjectDeletedException; 52 import com.genimen.djeneric.repository.oql.core.ParseException; 53 import com.genimen.djeneric.util.DjLogger; 54 55 60 public class RdbmsSession extends DjSession 61 { 62 Connection _conn; 63 64 72 protected RdbmsSession(DjPersistenceManager mgr) 73 { 74 super(mgr); 75 } 76 77 82 protected RdbmsPersistenceManager getRdbmsPersistenceManager() 83 { 84 return (RdbmsPersistenceManager) getPersistenceManager(); 85 } 86 87 public void releaseDatasources() 88 { 89 if (_conn != null) try 90 { 91 _conn.rollback(); 92 getRdbmsPersistenceManager().releaseToPool(_conn); 93 } 94 catch (SQLException x) 95 { 96 DjLogger.log(x); 100 } 101 _conn = null; 102 } 103 104 protected void assureConnection() throws DjenericException 105 { 106 if (_conn == null) _conn = getRdbmsPersistenceManager().getConnection(); 107 } 108 109 116 protected Connection getConnection() throws DjenericException 117 { 118 if (!isValid()) throw new DjenericException(Messages.getString("global.SessionClosed")); 119 assureConnection(); 120 return _conn; 121 } 122 123 129 public void commit() throws DjenericException 130 { 131 try 132 { 133 assureConnection(); 134 postChanges(); 135 if (shouldTrace(DjPersistenceManager.TRACE_FLOW)) trace("Database committed"); 136 _conn.commit(); 137 notifyApplySuccesfull(); 138 } 139 catch (SQLException x) 140 { 141 rollback(); 142 throw new DjenericException(x); 143 } 144 } 145 146 152 public void rollback() throws DjenericException 153 { 154 if (!isValid()) throw new DjenericException(Messages.getString("global.SessionClosed")); 155 try 156 { 157 assureConnection(); 158 _conn.rollback(); 159 } 160 catch (SQLException x) 161 { 162 throw new DjenericException(x); 163 } 164 } 165 166 169 public void close() 170 { 171 if (!isValid()) return; 172 releaseDatasources(); 174 setValid(false); 175 reset(); 177 if (shouldTrace(DjPersistenceManager.TRACE_FLOW)) trace(Messages.getString("global.SessionClosed")); 178 } 179 180 189 public SqlStatement getInternalSqlStatement(String stmt) throws DjenericException 190 { 191 if (!isValid()) throw new DjenericException(Messages.getString("global.SessionClosed")); 192 try 193 { 194 assureConnection(); 195 SqlStatement ss = new SqlStatement(_conn, stmt, stmt); 196 RdbmsPersistenceManager mgr = (RdbmsPersistenceManager) getPersistenceManager(); 197 DjContext context = mgr.getCurrentContext(); 198 if (context != null && ss.hasParameter(RdbmsPersistenceManager.CONTEXT_PARAM_NAME)) 199 { 200 ss.setLong(RdbmsPersistenceManager.CONTEXT_PARAM_NAME, context.getId()); 201 } 202 return ss; 203 } 204 catch (SQLException x) 205 { 206 throw new DjenericException(x); 207 } 208 } 209 210 219 public SqlStatement getSqlStatement(String stmt) throws DjenericException 220 { 221 if (!isValid()) throw new DjenericException(Messages.getString("global.SessionClosed")); 222 try 223 { 224 assureConnection(); 225 RdbmsPersistenceManager mgr = (RdbmsPersistenceManager) getPersistenceManager(); 226 SqlStatement ss = new SqlStatement(_conn, mgr.external2internalStatement(stmt), stmt); 227 ss.setCommitAllowed(isCommitAllowed()); 228 229 DjContext context = mgr.getCurrentContext(); 230 if (context != null && ss.hasParameter(RdbmsPersistenceManager.CONTEXT_PARAM_NAME)) 231 { 232 ss.setLong(RdbmsPersistenceManager.CONTEXT_PARAM_NAME, context.getId()); 233 } 234 235 return ss; 236 } 237 catch (SQLException x) 238 { 239 throw new DjenericException(x); 240 } 241 242 } 243 244 253 public DjObject createObject(DjExtent extent) throws DjenericException 254 { 255 if (!isValid()) throw new DjenericException(Messages.getString("global.SessionClosed")); 256 RdbmsDjenericObject po = new RdbmsDjenericObject(this, extent); 257 258 po.setTransient(extent.isTransient()); 259 260 if (shouldTrace(DjPersistenceManager.TRACE_FLOW)) trace("Object of type " + extent.getObjectType() + " created"); 261 return po; 262 } 263 264 275 public DjObject getObject(DjExtent extent, long id) throws DjenericException 276 { 277 DjObject po = doGetObject(extent, id); 278 if (po == null) throw new ObjectDeletedException(Messages.getString("RdbmsSession.probablyDeleted", extent 279 .getNameSingular(), String.valueOf(id)), po); 280 return po; 281 } 282 283 private DjObject doGetObject(DjExtent extent, long id) throws DjenericException 284 { 285 if (!isValid()) throw new DjenericException(Messages.getString("global.SessionClosed")); 286 try 287 { 288 DjObject loadedAlready = getFromSession(id); 291 if (loadedAlready != null) 292 { 293 if (!loadedAlready.isMarkedForDelete()) return loadedAlready; 296 return null; 297 } 298 299 RdbmsDjenericObject po = null; 300 301 if (getRdbmsPersistenceManager().isInPolymorphMode()) 311 { 312 SqlStatement stmt = getInternalSqlStatement("select * from " + RdbmsPersistenceManager.POLYMORPH_TABLE 313 + " where " + RdbmsPersistenceManager.MAPPING_OBJECT_ID + " = :id"); 314 stmt.setLong("id", id); 315 ResultSet rs = null; 316 317 try 318 { 319 rs = stmt.executeQuery(); 320 if (rs.next()) 321 { 322 String tableAlias = rs.getString(RdbmsPersistenceManager.INTERNAL_TYPE_COLUMN); 323 po = (RdbmsDjenericObject) createObject(getPersistenceManager().getExtentByInternalCode(tableAlias)); 324 po.setFromRecord(rs, false); 325 } 326 } 327 finally 328 { 329 if (rs != null) rs.close(); 330 stmt.close(); 331 } 332 } 333 else 334 { 335 SqlStatement stmt = getSqlStatement("select * from " + extent.getName() + " where " 336 + extent.getIdProperty().getName() + " = :id"); 337 stmt.setLong("id", id); 338 ResultSet rs = null; 339 340 try 341 { 342 rs = stmt.executeQuery(); 343 if (rs.next()) 344 { 345 po = (RdbmsDjenericObject) createObject(extent); 346 po.setFromRecord(rs, true); 347 } 348 else 349 { 350 DjExtent[] specs = extent.getSpecializations(); 351 for (int i = 0; i < specs.length; i++) 352 { 353 DjObject obj = doGetObject(specs[i], id); 354 if (obj != null) return obj; 355 } 356 } 357 } 358 finally 359 { 360 if (rs != null) rs.close(); 361 stmt.close(); 362 } 363 } 364 return po; 365 } 366 catch (SQLException x) 367 { 368 throw new DjenericException(x); 369 } 370 371 } 372 373 private String translateOperator(String operator, boolean valueIsNull) 374 { 375 if (valueIsNull) 376 { 377 if (operator.equals("!=")) return " is not "; 378 if (operator.equals("==")) return " is "; 379 } 380 381 if (operator.equals("!=")) return "<>"; 382 if (operator.equals("==")) return "="; 383 return operator; 384 } 385 386 private DjList getObjects(DjExtent ext, DjObjectMatcher qbe, boolean forceReloadFromDB, boolean addFromSession) 387 throws DjenericException 388 { 389 if (!isValid()) throw new DjenericException(Messages.getString("global.SessionClosed")); 390 try 391 { 392 DjList results = new DjList(); 393 results.setStoredTypeName(ext); 394 if (addFromSession) addModifiedObjectsFromSession(ext, qbe, results, false); 397 398 SqlStatement stmt = setupStatement(ext, qbe); 399 400 ResultSet rs = null; 401 String idColumnName = ext.getIdProperty().getName(); 402 try 403 { 404 rs = stmt.executeQuery(); 405 while (rs.next()) 406 { 407 long id = rs.getLong(idColumnName); 408 RdbmsDjenericObject po = (RdbmsDjenericObject) getFromSession(id); 409 if (po == null) 410 { 411 po = (RdbmsDjenericObject) createObject(ext); 412 po.setFromRecord(rs, true); 413 results.add(po); 414 } 415 else 416 { 417 if (!po.isMarkedForDelete()) 419 { 420 if (addFromSession && po.isModified()) 423 { } 425 else 426 { 427 results.add(po); 429 } 430 if (forceReloadFromDB) po.reload(); 431 } 432 } 433 } 434 } 435 finally 436 { 437 if (rs != null) rs.close(); 438 stmt.close(); 439 } 440 441 DjExtent[] specializations = ext.getSpecializations(); 444 for (int i = 0; i < specializations.length; i++) 445 { 446 results.addAll(getObjects(specializations[i], qbe, forceReloadFromDB, false)); 447 } 448 return results; 449 } 450 catch (SQLException x) 451 { 452 throw new DjenericException(x); 453 } 454 } 455 456 467 public DjList getObjects(DjObjectMatcher qbe, boolean forceReloadFromDB) throws DjenericException 468 { 469 DjList result = getObjects(qbe.getExtent(), qbe, forceReloadFromDB, true); 470 result.setStoredTypeName(qbe.getExtent()); 471 472 return result; 473 } 474 475 486 public DjList getObjects(DjExtent ext, boolean forceReloadFromDB) throws DjenericException 487 { 488 DjList result = getObjects(ext, null, forceReloadFromDB, true); 489 result.setStoredTypeName(ext); 490 491 return result; 492 } 493 494 private DjCursor getObjectsCursor(DjExtent ext, DjObjectMatcher qbe, boolean forceReloadFromDB, boolean addFromSession) 495 throws DjenericException 496 { 497 if (!isValid()) throw new DjenericException(Messages.getString("global.SessionClosed")); 498 try 499 { 500 DjList sessionObjects = new DjList(); 501 sessionObjects.setStoredTypeName(ext); 502 if (addFromSession) addModifiedObjectsFromSession(ext, qbe, sessionObjects, false); 505 506 SqlStatement stmt = setupStatement(ext, qbe); 507 508 RdbmsCursor result = new RdbmsCursor(this, ext, stmt, qbe, sessionObjects, forceReloadFromDB); 509 510 DjExtent specs[] = ext.getSpecializations(); 511 for (int i = 0; i < specs.length; i++) 512 { 513 result.chain(getObjectsCursor(specs[i], qbe, forceReloadFromDB, false)); 514 } 515 516 return result; 517 } 518 catch (SQLException x) 519 { 520 throw new DjenericException(x); 521 } 522 } 523 524 535 public DjCursor getObjectsCursor(DjExtent ext, boolean forceReloadFromDB) throws DjenericException 536 { 537 return getObjectsCursor(ext, null, forceReloadFromDB, true); 538 } 539 540 551 public DjCursor getObjectsCursor(DjObjectMatcher qbe, boolean forceReloadFromDB) throws DjenericException 552 { 553 return getObjectsCursor(qbe.getExtent(), qbe, forceReloadFromDB, true); 554 } 555 556 573 protected void addValidMasterObjects(DjExtent masterExtent, long restrictingOid, String restrictingPropertyName, 574 boolean forceReloadFromDB, DjList results) throws DjenericException 575 { 576 try 577 { 578 String masterExtentName = masterExtent.getName(); 579 SqlStatement stmt = getSqlStatement("select * from " + masterExtentName + " where " + restrictingPropertyName 580 + " = :restrictingOid"); 581 582 stmt.setLong("restrictingOid", restrictingOid); 583 584 ResultSet rs = null; 585 586 try 587 { 588 rs = stmt.executeQuery(); 589 while (rs.next()) 590 { 591 RdbmsDjenericObject po = (RdbmsDjenericObject) getFromSession(rs.getLong(masterExtent.getIdProperty() 592 .getName())); 593 if (po == null) 594 { 595 po = (RdbmsDjenericObject) createObject(masterExtent); 596 po.setFromRecord(rs, true); 597 results.add(po); 598 } 599 else 600 { 601 if (!po.isMarkedForDelete()) 603 { 604 results.add(po); 605 if (forceReloadFromDB) po.reload(); 606 } 607 608 } 609 } 610 } 611 finally 612 { 613 if (rs != null) rs.close(); 614 stmt.close(); 615 } 616 DjExtent[] specializations = masterExtent.getSpecializations(); 617 for (int i = 0; i < specializations.length; i++) 618 { 619 addValidMasterObjects(specializations[i], restrictingOid, restrictingPropertyName, forceReloadFromDB, results); 620 } 621 } 622 catch (SQLException x) 623 { 624 throw new DjenericException(x); 625 } 626 } 627 628 637 protected DjObject getFromSession(long id) throws DjenericException 638 { 639 return super.getFromSession(id); 640 } 641 642 private void setQbeParameters(SqlStatement stmt, DjQueryByExample qbe) throws SQLException 643 { 644 for (int i = 0; i < qbe.getPropertyCount(); i++) 645 { 646 if (!qbe.isNull(i)) 647 { 648 DjProperty prop = qbe.getProperty(i); 649 if (prop.getTypeCode() == DjDomain.INT_TYPE) stmt.setInt(prop.getName(), qbe.getInt(i)); 650 else if (prop.getTypeCode() == DjDomain.BIGDECIMAL_TYPE) stmt.setBigDecimal(prop.getName(), qbe 651 .getBigDecimal(i)); 652 else if (prop.getTypeCode() == DjDomain.DATE_TYPE) 653 { 654 if (qbe.getDate(i) instanceof java.sql.Timestamp ) stmt.setTimestamp(prop.getName(), (java.sql.Timestamp ) qbe 655 .getDate(i)); 656 else stmt.setTimestamp(prop.getName(), new java.sql.Timestamp (((java.util.Date ) qbe.getDate(i)).getTime())); 657 } 658 else if (prop.getTypeCode() == DjDomain.LONG_TYPE) stmt.setLong(prop.getName(), qbe.getLong(i)); 659 else if (prop.getTypeCode() == DjDomain.STRING_TYPE) stmt.setString(prop.getName(), qbe.getString(i)); 660 } 661 } 662 } 663 664 private SqlStatement setupStatement(DjExtent ext, DjObjectMatcher qbe) throws SQLException , DjenericException 665 { 666 if (qbe == null) 667 { 668 return setupDefaultStatement(ext); 669 } 670 else if (qbe instanceof DjQueryByExample) 671 { 672 return setupStatementUsingQbe(ext, (DjQueryByExample) qbe); 673 } 674 675 if (qbe instanceof DjOql) 676 { 677 return setupStatementUsingOql(ext, (DjOql) qbe); 678 } 679 680 throw new DjenericException(Messages.getString("RdbmsSession.unableToHandle", qbe.getClass().getName())); 681 } 682 683 private SqlStatement setupStatementUsingQbe(DjExtent ext, DjQueryByExample qbe) throws SQLException , 684 DjenericException 685 { 686 687 String sqlStmt = "select * from " + ext.getName(); 688 689 boolean first = true; 690 for (int i = 0; i < qbe.getPropertyCount(); i++) 691 { 692 if (!qbe.isNull(i) || qbe.hasOperatorFor(i)) 693 { 694 if (first) sqlStmt += " where "; 695 else sqlStmt += " and "; 696 first = false; 697 698 DjProperty prop = qbe.getProperty(i); 699 700 if (qbe.isNull(i)) 703 { 704 sqlStmt += prop.getName() + " " + translateOperator(qbe.getOperator(i), true) + " null"; 705 } 706 else 707 { 708 sqlStmt += prop.getName() + " " + translateOperator(qbe.getOperator(i), false) + " :" + prop.getName(); 709 } 710 } 711 } 712 713 SqlStatement stmt = getSqlStatement(sqlStmt); 714 setQbeParameters(stmt, qbe); 715 716 return stmt; 717 } 718 719 private SqlStatement setupDefaultStatement(DjExtent ext) throws DjenericException 720 { 721 String sqlStmt = "select * from " + ext.getName(); 722 SqlStatement stmt = getSqlStatement(sqlStmt); 723 return stmt; 724 } 725 726 private SqlStatement setupStatementUsingOql(DjExtent ext, DjOql oql) throws SQLException , DjenericException 727 { 728 String sqlStmt; 729 try 730 { 731 if (oql.getExtent() != ext) oql.setBaseClassExtent(ext); 734 735 String fromWhere = oql.getFromWhereClause(); 736 sqlStmt = "select "; 737 if (!oql.isResultUnique()) sqlStmt += "distinct "; 738 sqlStmt += oql.getAlias() + ".* " + fromWhere; 739 } 740 catch (ParseException e) 741 { 742 throw new DjenericException(e); 743 } 744 745 SqlStatement stmt = getSqlStatement(sqlStmt); 746 setOqlParameters(stmt, oql); 747 return stmt; 748 } 749 750 private void setOqlParameters(SqlStatement stmt, DjOql oql) throws SQLException , DjenericException 751 { 752 HashMap parameters = oql.getParameters(); 753 Iterator it = parameters.keySet().iterator(); 754 755 while (it.hasNext()) 756 { 757 String name = it.next().toString(); 758 Object value = parameters.get(name); 759 760 if (value instanceof Integer ) stmt.setInt(name, ((Integer ) value).intValue()); 761 else if (value instanceof BigDecimal ) stmt.setBigDecimal(name, (BigDecimal ) value); 762 else if (value instanceof java.sql.Timestamp ) stmt.setTimestamp(name, (java.sql.Timestamp ) value); 763 else if (value instanceof java.util.Date ) stmt.setTimestamp(name, new java.sql.Timestamp (((java.util.Date ) value) 764 .getTime())); 765 else if (value instanceof Long ) stmt.setLong(name, ((Long ) value).longValue()); 766 else if (value instanceof String ) stmt.setString(name, (String ) value); 767 else if (value instanceof DjObject) stmt.setLong(name, ((DjObject) value).getObjectId()); 768 else if (value == null) stmt.setNull(name, Types.NULL); 769 else throw new SQLException (Messages 770 .getString("RdbmsSession.unsupportedOqlParameter", value.getClass().getName())); 771 } 772 } 773 } | Popular Tags |