| 1 64 65 package com.jcorporate.expresso.core.db; 66 67 import com.jcorporate.expresso.core.db.config.JDBCConfig; 68 import com.jcorporate.expresso.core.db.config.JNDIConfig; 69 import com.jcorporate.expresso.core.db.datasource.DSException; 70 import com.jcorporate.expresso.core.db.datasource.JndiDataSource; 71 import com.jcorporate.expresso.core.dbobj.DBField; 72 import com.jcorporate.expresso.core.misc.ConfigManager; 73 import com.jcorporate.expresso.core.misc.ConfigurationException; 74 import com.jcorporate.expresso.core.misc.StringUtil; 75 import com.jcorporate.expresso.kernel.util.ClassLocator; 76 import org.apache.log4j.Logger; 77 78 import java.io.PrintWriter ; 79 import java.sql.CallableStatement ; 80 import java.sql.Connection ; 81 import java.sql.DatabaseMetaData ; 82 import java.sql.DriverManager ; 83 import java.sql.PreparedStatement ; 84 import java.sql.ResultSet ; 85 import java.sql.ResultSetMetaData ; 86 import java.sql.SQLException ; 87 import java.sql.Statement ; 88 import java.util.ArrayList ; 89 import java.util.Date ; 90 import java.util.Enumeration ; 91 import java.util.HashMap ; 92 import java.util.Hashtable ; 93 import java.util.Properties ; 94 import java.util.Vector ; 95 96 97 106 public class DBConnection { 107 108 111 public static final String DEFAULT_DB_CONTEXT_NAME = "default"; 112 113 116 private int connectionId = 0; 117 118 121 private String dbDriverType = ""; 122 123 126 private String dbDriver = ""; 127 128 131 private String dbURL = ""; 132 133 136 private String dbConnectFormat = ""; 137 138 141 private Statement stmnt = null; 142 143 146 private int lastUpdateCount = 0; 147 148 151 private String myDescription = "no description"; 152 153 156 private boolean isConnected = false; 157 158 161 private Connection myConnection; 162 163 166 private EscapeHandler escapeHandler = null; 167 168 171 private PreparedStatement preparedStatement = null; 172 173 176 private CallableStatement callableStatement = null; 177 178 181 private ResultSet myResultSet; 182 183 186 private String strSQL; 187 188 191 private String myLogin = ""; 192 193 196 private String myPassword = ""; 197 198 202 private boolean currentAvailable = false; 203 204 207 private static final String THIS_CLASS = DBConnection 208 .class.getName() + "."; 209 210 213 private long lastTouched = System.currentTimeMillis(); 215 216 219 private long createdTime = System.currentTimeMillis(); 220 221 224 private String dateTimeType = DBField.DATETIME_TYPE; 225 226 229 private boolean immortal = false; 230 231 234 private static Logger log = Logger.getLogger(DBConnection.class); 235 236 241 private static Logger sqlLog = Logger.getLogger("com.jcorporate.expresso.core.db.SQL"); 242 243 246 private String dbName = DEFAULT_DB_CONTEXT_NAME; 247 248 255 public static final int LIMITATION_DISABLED = 0; 256 257 270 public static final int LIMITATION_AFTER_TABLE = 1; 271 272 273 286 public static final int LIMITATION_AFTER_WHERE = 2; 287 288 301 public static final int LIMITATION_AFTER_ORDER_BY = 3; 302 303 316 public static final int LIMITATION_AFTER_SELECT = 4; 317 318 338 private int limitationPosition = LIMITATION_DISABLED; 339 340 341 348 public static final int TRANSACTION_NORMAL_MODE = 1; 349 350 357 public static final int TRANSACTION_DIRTY_MODE = 2; 358 359 366 public static final int TRANSACTION_RESTRICTIVE_MODE = 3; 367 368 375 public static final int TRANSACTION_EXCLUSIVE_MODE = 4; 376 377 378 386 private int transactionCommittedMode = TRANSACTION_NORMAL_MODE; 387 388 396 private int transactionUncommittedMode = TRANSACTION_DIRTY_MODE; 397 398 406 private int transactionRepeatableMode = TRANSACTION_RESTRICTIVE_MODE; 407 408 416 private int transactionSerializableMode = TRANSACTION_EXCLUSIVE_MODE; 417 418 439 private String limitationSyntax = null; 440 441 448 private JDBCConfig myJdbc = null; 449 450 451 454 protected DBConnectionPool parentPool = null; 455 456 488 public DBConnection(String newDBDriver, String newDBURL, 489 String newDBConnectFormat) 490 throws DBException { 491 connectionSetup("manager", newDBDriver, newDBURL, newDBConnectFormat); 492 try { 493 myJdbc = ConfigManager.getJdbcRequired(dbName); 494 } catch (ConfigurationException e) { 495 throw new DBException(e); 496 } 497 } 498 499 500 508 public DBConnection(JDBCConfig newConfigJdbc) throws DBException { 509 if (newConfigJdbc != null) { 510 myJdbc = newConfigJdbc; 511 connectionSetup(newConfigJdbc.getDriverType(), newConfigJdbc.getDriver(), 512 newConfigJdbc.getUrl(), newConfigJdbc.getConnectFormat()); 513 } else { 514 String myName = (THIS_CLASS + 515 "DBConnection(ConfigJdbc)"); 516 throw new DBException(myName + ":ConfigJdbc not initialiazed "); 517 } 518 } 519 520 554 public DBConnection(String newDBDriverType, String newDBDriver, String newDBURL, 555 String newDBConnectFormat) 556 throws DBException { 557 connectionSetup(newDBDriverType, newDBDriver, newDBURL, newDBConnectFormat); 558 try { 559 myJdbc = ConfigManager.getJdbcRequired(dbName); 560 } catch (ConfigurationException e) { 561 throw new DBException(e); 562 } 563 } 564 565 566 576 public void connectionSetup(String newDBDriverType, String newDBDriver, String newDBURL, 577 String newDBConnectFormat) 578 throws DBException { 579 580 dbDriverType = newDBDriverType; 581 dbDriver = newDBDriver; 582 dbURL = newDBURL; 583 dbConnectFormat = newDBConnectFormat; 584 585 try { 586 if (!dbDriverType.equalsIgnoreCase("datasource")) { 587 ClassLocator.loadClass(dbDriver).newInstance(); 588 } 589 590 Properties p = System.getProperties(); 591 p.put("jdbc.drivers", dbDriver); 592 System.setProperties(p); 593 } catch (Exception se) { 594 log.error("Cant find/load the database " + 595 "driver '" + dbDriver, se); 596 String myName = (THIS_CLASS + 597 "DBConnection(String, String, String)"); 598 throw new DBException(myName + ":Cant find/load the database " + 599 "driver '" + dbDriver + "' (" + 600 myDescription + ")"); 601 } 602 603 touch(); 604 605 609 if (log.isDebugEnabled()) { 610 try { 611 if (!dbDriverType.equalsIgnoreCase("datasource")) { 612 DriverManager.setLogWriter(new PrintWriter (java.lang.System.out)); 613 } 614 } catch (java.lang.SecurityException se) { 615 log.warn("Error setting SQL Log stream: ", se); 616 } 617 } 618 } 619 620 623 public void checkTimeOut() 624 throws DBException { 625 if (currentAvailable) { 626 throw new DBException(THIS_CLASS + "checkTimeOut()" + ":Connection '" + getDescription() + 627 "' is not available - it may have timed out and been " + 628 "returned to connection pool. Please try again."); 629 } 630 } 631 632 633 636 public synchronized void clear() 637 throws DBException { 638 if (myResultSet != null) { 639 try { 640 myResultSet.close(); 641 } catch (SQLException ex) { 642 log.warn("Error closing resultset", ex); 643 } 644 myResultSet = null; 645 } 646 if (stmnt != null) { 647 try { 648 stmnt.close(); 649 } catch (SQLException ex) { 650 log.warn("Error closing statement", ex); 651 } 652 stmnt = null; 653 } 654 655 if (preparedStatement != null) { 656 try { 657 preparedStatement.close(); 658 } catch (SQLException ex) { 659 log.warn("Error closing prepared statement", ex); 660 } 661 preparedStatement = null; 662 } 663 664 this.strSQL = null; 665 } 666 667 668 675 public synchronized void commit() 676 throws DBException { 677 678 if (this.supportsTransactions()) { 679 try { 680 myConnection.commit(); 681 } catch (SQLException se) { 682 throw new DBException(THIS_CLASS + "commit():Could not commit (" + 683 myDescription + ")", se.getMessage()); 684 } 685 } 686 687 touch(); 688 } 689 690 691 698 public synchronized void connect(String newLogin, String newPassword) 699 throws DBException { 700 createdTime = System.currentTimeMillis(); 701 myLogin = newLogin.trim(); 702 myPassword = newPassword.trim(); 703 704 if (dbConnectFormat == null) { 705 String myName = (THIS_CLASS + "connect(String, String)"); 706 throw new DBException(myName + 707 ":dbConnectFormat argument cannot " + 708 "be null"); 709 } 710 try { 711 if (dbConnectFormat.equals("1")) { 712 if (log.isDebugEnabled()) { 713 log.debug("Using Connect Format #1: DriverManager.getConnection(" + 714 dbURL + "," + newLogin + "," + newPassword + 715 ");"); 716 } 717 718 myConnection = DriverManager.getConnection(dbURL, newLogin, 719 newPassword); 720 } else if (dbConnectFormat.equals("2")) { 721 myConnection = DriverManager.getConnection(dbURL + "?user=" + 722 newLogin + 723 ";password=" + 724 newPassword); 725 } else if (dbConnectFormat.equals("3")) { 726 Properties props = new Properties (); 727 props.put("user", newLogin); 728 props.put("password", newPassword); 729 myConnection = DriverManager.getConnection(dbURL, props); 730 } else if (dbConnectFormat.equals("4")) { 731 myConnection = DriverManager.getConnection(dbURL + "?user=" + 732 newLogin + 733 "&password=" + 734 newPassword); 735 } else { 736 String myName = (THIS_CLASS + "connect(String, String)"); 737 throw new DBException(myName + ":Unknown dbConnectFormat " + 738 "choice:" + dbConnectFormat); 739 } 740 } catch (SQLException se) { 741 String myName = (THIS_CLASS + "connect(String, String)"); 742 throw new DBException(myName + 743 ":Cant get connection to database via driver '" + 744 dbDriver + "' and URL '" + dbURL + "' (" + 745 myDescription + ")", se.getMessage()); 746 } 747 if (myConnection == null) { 748 String myName = (THIS_CLASS + "connect(String, String)"); 749 throw new DBException(myName + 750 ":Cant get connection to database via driver '" + 751 dbDriver + "' and URL '" + dbURL + 752 ":JDBC returned a null connection. (" + 753 myDescription + ")"); 754 } 755 756 isConnected = true; 758 this.setAutoCommit(true); 759 touch(); 760 } 761 762 771 public synchronized void connect(JndiDataSource newJndiDS) throws DBException { 772 createdTime = System.currentTimeMillis(); 773 myLogin = myJdbc.getLogin().trim(); 774 myPassword = myJdbc.getPassword().trim(); 775 if (parentPool.getJNDIConfig(myJdbc) == null) { 776 String myName = (THIS_CLASS + "connect(JndiDataSource)"); 777 throw new DBException(myName + " JNDI info configure for datasource"); 778 } 779 780 if (dbConnectFormat == null) { 781 String myName = (THIS_CLASS + "connect(JndiDataSource)"); 782 throw new DBException(myName + 783 ":dbConnectFormat argument cannot " + 784 "be null"); 785 } 786 try { 787 if (dbConnectFormat.equals("1")) { 788 if (log.isDebugEnabled()) { 789 log.debug("Using Connect Format #1: Datasource.getConnection(" + 790 dbURL + "," + myLogin + "," + myPassword + 791 ");"); 792 } 793 794 myConnection = newJndiDS.getConnection(); 795 } else { 796 if (dbConnectFormat.equals("2")) { 797 myConnection = newJndiDS.getConnection(myLogin, myPassword); 798 } else { 799 String myName = (THIS_CLASS + "connect(JndiDataSource)"); 800 throw new DBException(myName + ":Unknown dbConnectFormat " + 801 "choice:" + dbConnectFormat); 802 } 803 } 804 } catch (DSException se) { 805 String myName = (THIS_CLASS + "connect(JndiDataSource)"); 806 throw new DBException(myName + 807 ":Cannot get connection to database via JNDI DataSource '" + 808 dbURL + "' (" + 809 myDescription + ")", se.getMessage()); 810 } 811 if (myConnection == null) { 812 String myName = (THIS_CLASS + "connect(JndiDataSource)"); 813 throw new DBException(myName + 814 ":Cannot get connection to database via JNDI DataSource '" + 815 "' URL '" + dbURL + 816 ":JNDI JDBC returned a null connection. (" + 817 myDescription + ")"); 818 } 819 820 isConnected = true; 822 this.setAutoCommit(true); 823 touch(); 824 } 825 826 832 public Statement createStatement() { 833 try { 834 if (myConnection == null) { 835 return null; 836 } 837 838 stmnt = myConnection.createStatement(); 839 840 return stmnt; 841 } catch (SQLException e) { 842 log.error(e); 843 } 844 845 return stmnt; 846 } 847 848 855 public PreparedStatement createPreparedStatement(String sqlString) { 856 try { 857 if (myConnection == null) { 858 return null; 859 } 860 touch(); 861 862 if (preparedStatement != null) { 863 try { 864 preparedStatement.close(); 865 } catch (SQLException ex) { 866 log.warn("Error closing older prepared statement: ", ex); 867 } 868 } 869 870 if (sqlLog.isDebugEnabled()) { 871 sqlLog.debug("Connection " + getId() + " preparing statement from:'" + sqlString + 872 "' on db '" + getDataContext() + "'"); 873 &
|