KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > core > db > DBConnection


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

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 JavaDoc;
79 import java.sql.CallableStatement JavaDoc;
80 import java.sql.Connection JavaDoc;
81 import java.sql.DatabaseMetaData JavaDoc;
82 import java.sql.DriverManager JavaDoc;
83 import java.sql.PreparedStatement JavaDoc;
84 import java.sql.ResultSet JavaDoc;
85 import java.sql.ResultSetMetaData JavaDoc;
86 import java.sql.SQLException JavaDoc;
87 import java.sql.Statement JavaDoc;
88 import java.util.ArrayList JavaDoc;
89 import java.util.Date JavaDoc;
90 import java.util.Enumeration JavaDoc;
91 import java.util.HashMap JavaDoc;
92 import java.util.Hashtable JavaDoc;
93 import java.util.Properties JavaDoc;
94 import java.util.Vector JavaDoc;
95
96
97 /**
98  * Generic database connection object - hides the implementation
99  * details of using jdbc and allows for JDBC message and exceptions to be
100  * handled better than by default.
101  * DBConnection's are also designed to be used in conjunction with connection
102  * pooling, and have special methods to support this.
103  *
104  * @author Michael Nash
105  */

106 public class DBConnection {
107
108     /**
109      * Constant name for the 'Default' database context
110      */

111     public static final String JavaDoc DEFAULT_DB_CONTEXT_NAME = "default";
112
113     /**
114      * Every connection handled by the pool gets an ID number assigned
115      */

116     private int connectionId = 0;
117
118     /**
119      * Driver Type object name to use for JDBC connection
120      */

121     private String JavaDoc dbDriverType = "";
122
123     /**
124      * Driver object name to use for JDBC connection
125      */

126     private String JavaDoc dbDriver = "";
127
128     /**
129      * URL to use when connecting via the given driver
130      */

131     private String JavaDoc dbURL = "";
132
133     /**
134      * Format to use for the connect statement
135      */

136     private String JavaDoc dbConnectFormat = "";
137
138     /**
139      * Current JDBC statement
140      */

141     private Statement JavaDoc stmnt = null;
142
143     /**
144      * Number of rows affected by last operation
145      */

146     private int lastUpdateCount = 0;
147
148     /**
149      * Description of this connection
150      */

151     private String JavaDoc myDescription = "no description";
152
153     /**
154      * Is this connection object actually connected to the database yet?
155      */

156     private boolean isConnected = false;
157
158     /**
159      * JDBC connection object
160      */

161     private Connection JavaDoc myConnection;
162
163     /**
164      * The escape character handler for a particular database
165      */

166     private EscapeHandler escapeHandler = null;
167
168     /**
169      * Any prepared statements that might be run
170      */

171     private PreparedStatement JavaDoc preparedStatement = null;
172
173     /**
174      * Any callable statements that might be run
175      */

176     private CallableStatement JavaDoc callableStatement = null;
177
178     /**
179      * Current result set
180      */

181     private ResultSet JavaDoc myResultSet;
182
183     /**
184      * The SQL statement that we run
185      */

186     private String JavaDoc strSQL;
187
188     /**
189      * Login name used to connect to the database
190      */

191     private String JavaDoc myLogin = "";
192
193     /**
194      * Password used to connect to the database
195      */

196     private String JavaDoc myPassword = "";
197
198     /**
199      * Is this connection available for use?
200      * (Used by connection pooling)
201      */

202     private boolean currentAvailable = false;
203
204     /**
205      * constant name to help with debugging
206      */

207     private static final String JavaDoc THIS_CLASS = DBConnection
208             .class.getName() + ".";
209
210     /**
211      * When was this connection last used?
212      */

213 // private Calendar lastTouched = null;
214
private long lastTouched = System.currentTimeMillis();
215
216     /**
217      * Time that the DBConnection was created.
218      */

219     private long createdTime = System.currentTimeMillis();
220
221     /**
222      * What database data type is being used for date/time fields?
223      */

224     private String JavaDoc dateTimeType = DBField.DATETIME_TYPE;
225
226     /**
227      * Don't time out this connection - it may take a while
228      */

229     private boolean immortal = false;
230
231     /**
232      * The main Connection Log
233      */

234     private static Logger log = Logger.getLogger(DBConnection.class);
235
236     /**
237      * The SQL Log Set this category to debug
238      * to see a trace of all sql statements
239      * issued against the main database
240      */

241     private static Logger sqlLog = Logger.getLogger("com.jcorporate.expresso.core.db.SQL");
242
243     /**
244      * The current data context
245      */

246     private String JavaDoc dbName = DEFAULT_DB_CONTEXT_NAME;
247
248     /**
249      * Limitation syntax database vendor specific optimisation is disabled
250      * <p/>
251      * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
252      *
253      * @since Expresso 4.0
254      */

255     public static final int LIMITATION_DISABLED = 0;
256
257     /**
258      * Insert the limitation syntax after TABLE nomination
259      * <code>
260      * SELECT {COLUMNS}... FROM {TABLE}
261      * <font color="#660066">{limitation-syntax}</font>
262      * [ WHERE {where_clause}... ]
263      * [ ORDER BY {order_by_clause}... ]
264      * </code>
265      * <p/>
266      * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
267      *
268      * @since Expresso 4.0
269      */

270     public static final int LIMITATION_AFTER_TABLE = 1;
271
272
273     /**
274      * Insert the limitation syntax after WHERE key word
275      * <code>
276      * SELECT {COLUMNS}... FROM {TABLE}
277      * [ WHERE {where_clause}... ]
278      * AND <font color="#660066">{limitation-syntax}</font>
279      * [ ORDER BY {order_by_clause}... ]
280      * </code>
281      * <p/>
282      * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
283      *
284      * @since Expresso 4.0
285      */

286     public static final int LIMITATION_AFTER_WHERE = 2;
287
288     /**
289      * Insert the limitation syntax after ORDER BY key words
290      * <code>
291      * SELECT {COLUMNS}... FROM {TABLE}
292      * [ WHERE {where_clause}... ]
293      * [ ORDER BY {order_by_clause}... ]
294      * <font color="#660066">{limitation-syntax}</font>
295      * </code>
296      * <p/>
297      * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
298      *
299      * @since Expresso 4.0
300      */

301     public static final int LIMITATION_AFTER_ORDER_BY = 3;
302
303     /**
304      * Insert the limitation syntax after TABLE nomination
305      * <code>
306      * SELECT <font color="#660066">{limitation-syntax}</font>
307      * {COLUMNS}... FROM {TABLE}
308      * [ WHERE {where_clause}... ]
309      * [ ORDER BY {order_by_clause}... ]
310      * </code>
311      * <p/>
312      * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
313      *
314      * @since Expresso 4.0
315      */

316     public static final int LIMITATION_AFTER_SELECT = 4;
317
318     /**
319      * Rowset Limitation Optimisation Syntax Position.
320      * Specifies a where in the SQL command the limitation string should be
321      * inserted.
322      * <p/>
323      * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
324      *
325      * @see DBConnectionPool#LIMITATION_DISABLED
326      * @see DBConnectionPool#LIMITATION_AFTER_TABLE
327      * @see DBConnectionPool#LIMITATION_AFTER_WHERE
328      * @see DBConnectionPool#LIMITATION_AFTER_ORDER_BY
329      * @see DBConnectionPool#LIMITATION_AFTER_SELECT
330      * @see com.jcorporate.expresso.core.dbobj.DBObject#searchAndRetrieveList
331      * @see com.jcorporate.expresso.core.dbobj.DBObject#getOffsetRecord()
332      * @see com.jcorporate.expresso.core
333      * .dbobj.DBObject#setOffsetRecord( int )
334      * @see com.jcorporate.expresso.core.dbobj.DBObject#getMaxRecords()
335      * @see com.jcorporate.expresso.core.dbobj.DBObject#setMaxRecords( int )
336      * @since Expresso 4.0
337      */

338     private int limitationPosition = LIMITATION_DISABLED;
339
340
341     /**
342      * Committed read transaction mode
343      * <p/>
344      * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
345      *
346      * @since Expresso 5.3
347      */

348     public static final int TRANSACTION_NORMAL_MODE = 1;
349
350     /**
351      * Uncommitted read transaction mode
352      * <p/>
353      * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
354      *
355      * @since Expresso 5.3
356      */

357     public static final int TRANSACTION_DIRTY_MODE = 2;
358
359     /**
360      * Repeatable read transaction mode
361      * <p/>
362      * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
363      *
364      * @since Expresso 5.3
365      */

366     public static final int TRANSACTION_RESTRICTIVE_MODE = 3;
367
368     /**
369      * Serializable read transaction mode
370      * <p/>
371      * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
372      *
373      * @since Expresso 5.3
374      */

375     public static final int TRANSACTION_EXCLUSIVE_MODE = 4;
376
377
378     /**
379      * Transaction isolation mode set : Default Expresso transaction mode.
380      * <p/>
381      * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
382      *
383      * @see Connection#TRANSACTION_READ_COMMITTED MODE
384      * @since Expresso 5.3
385      */

386     private int transactionCommittedMode = TRANSACTION_NORMAL_MODE;
387
388     /**
389      * Transaction isolation mode set
390      * <p/>
391      * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
392      *
393      * @see Connection#TRANSACTION_READ_UNCOMMITTED MODE
394      * @since Expresso 5.3
395      */

396     private int transactionUncommittedMode = TRANSACTION_DIRTY_MODE;
397
398     /**
399      * Transaction isolation mode set
400      * <p/>
401      * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
402      *
403      * @see Connection#TRANSACTION_REPEATABLE_READ MODE
404      * @since Expresso 5.3
405      */

406     private int transactionRepeatableMode = TRANSACTION_RESTRICTIVE_MODE;
407
408     /**
409      * Transaction isolation mode set
410      * <p/>
411      * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
412      *
413      * @see Connection#TRANSACTION_SERIALIZABLE MODE
414      * @since Expresso 5.3
415      */

416     private int transactionSerializableMode = TRANSACTION_EXCLUSIVE_MODE;
417
418     /**
419      * Rowset Limitation Optimisation Syntax String.
420      * Specifies a string to add database query to retrieve
421      * only a finite number of rows from the <code>ResultSet</code>.
422      * <p/>
423      * <p>For example for MYSQL the string should be
424      * <code>"LIMIT %offset% , %maxrecord%"</code>
425      * </p>
426      * <p/>
427      * <p>For example for ORACLE the string should be
428      * <code>"ROWNUM >= %offset% AND ROWNUM <=%endrecord%"</code>
429      * </p>
430      * <p/>
431      * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
432      *
433      * @see com.jcorporate.expresso.core.dbobj.DBObject#searchAndRetrieveList()
434      * @see com.jcorporate.expresso.core.dbobj
435      * .DBObject#setOffsetRecord( int )
436      * @see com.jcorporate.expresso.core.dbobj.DBObject#setMaxRecords( int )
437      * @since Expresso 4.0
438      */

439     private String JavaDoc limitationSyntax = null;
440
441     /**
442      * The JDBC Config get from expresso-config.xml
443      * author Yves Henri AMAIZO, Sun Jul 29 01:30:59 BST 2002
444      *
445      * @see com.jcorporate.expresso.core.misc.ConfigJdbc
446      * @since Expresso 4.0
447      */

448     private JDBCConfig myJdbc = null;
449
450
451     /**
452      * The ConnectionPool that created this connection.
453      */

454     protected DBConnectionPool parentPool = null;
455
456     /**
457      * Constructor
458      * Create a new connection object
459      *
460      * @param newDBDriver The class name of the JDBC driver to use for this
461      * connection
462      * @param newDBURL The URL passed to the driver to connect to the
463      * database
464      * @param newDBConnectFormat The style or format of the call to actually
465      * connect to the database. The options are as follows:
466      * <ol><li>1: Create the connection with a call to
467      * DriverManager.getConnection(dbURL, login,
468      * password) where login and password are the
469      * supplied login name and password</li>
470      * <li>2: Create the connection with a call to
471      * DriverManager.getConnection(dbURL + "?user="
472      * + login + ";password=" + password) where login
473      * and password are the supplied login and
474      * password</li>
475      * <li>3: Create the connection by setting the login
476      * and password into a properties object and
477      * calling DriverManager.getConnection(dbURL,
478      * props) where props is the created properties
479      * object</li>
480      * <li>4: Create the connection with a string like
481      * DriverManager.getConnection(dbURL
482      * + "?user="
483      * + newLogin + "&password=" + newPassword)</li>
484      * </ol>
485      * @throws DBException If the information provided cannot be used to
486      * create a new connection
487      */

488     public DBConnection(String JavaDoc newDBDriver, String JavaDoc newDBURL,
489                         String JavaDoc 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     /**
501      * Constructor
502      * Create a new connection object
503      *
504      * @param newConfigJdbc The JDBC driver configuration retrieve from the context
505      * @throws DBException If the information provided cannot be used to
506      * create a new connection
507      */

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 JavaDoc myName = (THIS_CLASS +
515                     "DBConnection(ConfigJdbc)");
516             throw new DBException(myName + ":ConfigJdbc not initialiazed ");
517         }
518     }
519
520     /**
521      * Constructor
522      * Create a new connection object
523      *
524      * @param newDBDriverType The JDBC driver Type name to use for this
525      * connection
526      * @param newDBDriver The class name of the JDBC driver to use for this
527      * connection
528      * @param newDBURL The URL passed to the driver to connect to the
529      * database
530      * @param newDBConnectFormat The style or format of the call to actually
531      * connect to the database. The options are as follows:
532      * <ol><li>1: Create the connection with a call to
533      * DriverManager.getConnection(dbURL, login,
534      * password) where login and password are the
535      * supplied login name and password</li>
536      * <li>2: Create the connection with a call to
537      * DriverManager.getConnection(dbURL + "?user="
538      * + login + ";password=" + password) where login
539      * and password are the supplied login and
540      * password</li>
541      * <li>3: Create the connection by setting the login
542      * and password into a properties object and
543      * calling DriverManager.getConnection(dbURL,
544      * props) where props is the created properties
545      * object</li>
546      * <li>4: Create the connection with a string like
547      * DriverManager.getConnection(dbURL
548      * + "?user="
549      * + newLogin + "&password=" + newPassword)</li>
550      * </ol>
551      * @throws DBException If the information provided cannot be used to
552      * create a new connection
553      */

554     public DBConnection(String JavaDoc newDBDriverType, String JavaDoc newDBDriver, String JavaDoc newDBURL,
555                         String JavaDoc 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     /**
567      * Sets up the connection whether JDBC or JNDI Datasources
568      *
569      * @param newDBDriverType The driver type, either &quote;datasource&quote; or another name
570      * if you want a straight JDBC Driver
571      * @param newDBDriver The driver name
572      * @param newDBURL the URL of the database driver
573      * @param newDBConnectFormat The connection format. See the DBConnection constructors
574      * for more information on what this paramter means.
575      */

576     public void connectionSetup(String JavaDoc newDBDriverType, String JavaDoc newDBDriver, String JavaDoc newDBURL,
577                                 String JavaDoc 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 JavaDoc p = System.getProperties();
591             p.put("jdbc.drivers", dbDriver);
592             System.setProperties(p);
593         } catch (Exception JavaDoc se) {
594             log.error("Cant find/load the database " +
595                     "driver '" + dbDriver, se);
596             String JavaDoc 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         /**
606          * If the DBConnection object's debugging level is set to DEBUG, enable
607          * tracing of the operation of the driver to standard output
608          */

609         if (log.isDebugEnabled()) {
610             try {
611                 if (!dbDriverType.equalsIgnoreCase("datasource")) {
612                     DriverManager.setLogWriter(new PrintWriter JavaDoc(java.lang.System.out));
613                 }
614             } catch (java.lang.SecurityException JavaDoc se) {
615                 log.warn("Error setting SQL Log stream: ", se);
616             }
617         }
618     } /* DBConnection(String, String, String) */
619
620     /**
621      * Checks if this connectino has timed out.
622      */

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     } /* checkTimeOut() */
631
632
633     /**
634      * Clear all result sets and statements associated with this connection
635      */

636     public synchronized void clear()
637             throws DBException {
638         if (myResultSet != null) {
639             try {
640                 myResultSet.close();
641             } catch (SQLException JavaDoc 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 JavaDoc 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 JavaDoc ex) {
659                 log.warn("Error closing prepared statement", ex);
660             }
661             preparedStatement = null;
662         }
663
664         this.strSQL = null;
665     } /* clear() */
666
667
668     /**
669      * Send a COMMIT to the database, closing the current transaction If the
670      * database driver claims it doesn't support transactions, then we skip
671      * this.
672      *
673      * @throws DBException If the commit does not succeed
674      */

675     public synchronized void commit()
676             throws DBException {
677
678         if (this.supportsTransactions()) {
679             try {
680                 myConnection.commit();
681             } catch (SQLException JavaDoc se) {
682                 throw new DBException(THIS_CLASS + "commit():Could not commit (" +
683                         myDescription + ")", se.getMessage());
684             }
685         }
686
687         touch();
688     } /* commit() */
689
690
691     /**
692      * Connect to the database, ready to execute statements
693      *
694      * @param newLogin Login user name to connect with
695      * @param newPassword Password to connect with
696      * @throws DBException If the connection does not succeed
697      */

698     public synchronized void connect(String JavaDoc newLogin, String JavaDoc newPassword)
699             throws DBException {
700         createdTime = System.currentTimeMillis();
701         myLogin = newLogin.trim();
702         myPassword = newPassword.trim();
703
704         if (dbConnectFormat == null) {
705             String JavaDoc 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 JavaDoc props = new Properties JavaDoc();
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 JavaDoc myName = (THIS_CLASS + "connect(String, String)");
737                 throw new DBException(myName + ":Unknown dbConnectFormat " +
738                         "choice:" + dbConnectFormat);
739             }
740         } catch (SQLException JavaDoc se) {
741             String JavaDoc 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 JavaDoc 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         // Open a connection
757
isConnected = true;
758         this.setAutoCommit(true);
759         touch();
760     } /* connect(String, String) */
761
762     /**
763      * Connect to the database, ready to execute statements
764      *
765      * @param newJndiDS a configuration bean describing the connection
766      * datasource properties.
767      * @throws DBException If the connection does not succeed
768      * author Yves Henri AMAIZO (Creation)
769      * @since Expresso 5.0
770      */

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 JavaDoc myName = (THIS_CLASS + "connect(JndiDataSource)");
777             throw new DBException(myName + " JNDI info configure for datasource");
778         }
779
780         if (dbConnectFormat == null) {
781             String JavaDoc 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 JavaDoc myName = (THIS_CLASS + "connect(JndiDataSource)");
800                     throw new DBException(myName + ":Unknown dbConnectFormat " +
801                             "choice:" + dbConnectFormat);
802                 }
803             }
804         } catch (DSException se) {
805             String JavaDoc 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 JavaDoc 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         // Open a connection
821
isConnected = true;
822         this.setAutoCommit(true);
823         touch();
824     } /* connect(JndiDataSource) */
825
826     /**
827      * Return a Statement object from this connection - for compatibility
828      * with the DBConnection object in Turbine
829      *
830      * @return The fully created statement
831      */

832     public Statement JavaDoc createStatement() {
833         try {
834             if (myConnection == null) {
835                 return null;
836             }
837
838             stmnt = myConnection.createStatement();
839
840             return stmnt;
841         } catch (SQLException JavaDoc e) {
842             log.error(e);
843         }
844
845         return stmnt;
846     } /* createStatement() */
847
848     /**
849      * Creates a <code>PreparedStatment</code> object.
850      *
851      * @param sqlString The string to create the prepared statement with.
852      * @return an instantiated prepared statement, that you then modify for
853      * your various parameters May return null if an exception occurred
854      */

855     public PreparedStatement JavaDoc createPreparedStatement(String JavaDoc 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 JavaDoc 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             }
874
875             preparedStatement = myConnection.prepareStatement(sqlString);
876         } catch (SQLException JavaDoc e) {
877             log.error(e);
878         }
879         return preparedStatement;
880     }
881
882     /**
883      * Clear a prepared statement associated with this record.
884      */

885     public void clearPreparedStatement() {
886         if (this.preparedStatement != null) {
887             try {
888                 preparedStatement.close();
889             } catch (SQLException JavaDoc ex) {
890                 log.warn("Error clearing prepared statement", ex);
891             }
892
893             preparedStatement = null;
894         }
895     }
896
897     /**
898      * Creates a <code>CallableStatment</code> object.
899      *
900      * @param sqlString The string to create the callable statement with.
901      * @return an instantiated callable statement, that you then modify for
902      * your various parameters May return null if an exception occurred
903      */

904     public CallableStatement JavaDoc createCallableStatement(String JavaDoc sqlString) {
905         try {
906             if (myConnection == null) {
907                 return null;
908             }
909             touch();
910
911             if (callableStatement != null) {
912                 try {
913                     callableStatement.close();
914                 } catch (SQLException JavaDoc ex) {
915                     log.warn("Error closing older callable statement: ", ex);
916                 }
917             }
918             callableStatement = myConnection.prepareCall(sqlString);
919         } catch (SQLException JavaDoc e) {
920             log.error(e);
921         }
922         return callableStatement;
923     }
924
925
926     /**
927      * Clear a callable statement associated with this record.
928      */

929     public void clearCallableStatement() {
930         if (this.callableStatement != null) {
931             try {
932                 callableStatement.close();
933             } catch (SQLException JavaDoc ex) {
934                 log.warn("Error clearing callable statement", ex);
935             }
936
937             callableStatement = null;
938         }
939     }
940
941
942     /**
943      * Close the connection to the database
944      *
945      * @throws DBException If the connection could not be closed successfully.
946      */

947     public synchronized void disconnect()
948             throws DBException {
949         try {
950             try {
951                 clear();
952             } catch (DBException ex) {
953                 log.error("Error clearing connection", ex);
954             }
955             if (isConnected) {
956                 try {
957                     if (myConnection.getAutoCommit() == false) {
958 // myConnection.commit();
959
myConnection.rollback();
960                     }
961                 } catch (SQLException JavaDoc ex) {
962                     log.error("Error commiting connection when closing");
963                 }
964
965                 myConnection.close();
966             }
967
968         } catch (SQLException JavaDoc se) {
969             throw new DBException(THIS_CLASS + "disconnect()" + ":Could not commit/close:" + " (" +
970                     myDescription + ")", se.getMessage());
971         }
972
973         if (!isConnected) {
974             log.warn(THIS_CLASS + "disconnect()" + ":Connection already closed (" + myDescription +
975                     ")");
976         }
977
978         myConnection = null;
979         isConnected = false;
980         immortal = false;
981     } /* disconnect() */
982
983
984     /**
985      * Execute the actual query
986      * Queries executed by this method are expected to return a result
987      * - use executeUpdate for queries that do not.
988      *
989      * @throws DBException If the query fails or is an update query.
990      */

991     public synchronized void execute()
992             throws DBException {
993         touch();
994
995         if (!isConnected) {
996             throw new DBException("Not connected to database " +
997                     "- called connect method first (" +
998                     myDescription + ", db/context '" +
999                     getDataContext() + "')");
1000        }
1001
1002        checkTimeOut();
1003
1004        try {
1005            if (myConnection == null) {
1006                throw new DBException("No current connection - " +
1007                        "connect to database failed: Unable to execute query:" +
1008                        strSQL + " (" + myDescription +
1009                        ", db/context '" + getDataContext() + "')");
1010            }
1011
1012            //
1013
//More robust recovery. Some databases will throw a sqlexception
1014
//if the resultset or statement is already closed
1015
//
1016
if (myResultSet != null) {
1017                try {
1018                    myResultSet.close();
1019                } catch (SQLException JavaDoc ex) {
1020                    log.warn("Error closing resultset", ex);
1021                }
1022                myResultSet = null;
1023            }
1024
1025            if (stmnt != null) {
1026                try {
1027                    stmnt.close();
1028                } catch (SQLException JavaDoc ex) {
1029                    log.warn("Error closing statement", ex);
1030                }
1031                stmnt = null;
1032            }
1033
1034
1035            //
1036
//If a prepared statement has been created and NO SQL has been created
1037
//the we assume we want a prepared statement to execute. Otherwise,
1038
//we execute a normal SQL Statement object
1039
//
1040
if (preparedStatement == null && strSQL != null && strSQL.length() > 0) {
1041                stmnt = myConnection.createStatement();
1042
1043                if (stmnt == null) {
1044                    throw new DBException("createStatement() returned " +
1045                            "null statement - unable to execute query:" +
1046                            strSQL + " (" + myDescription +
1047                            ", db/context '" + getDataContext() + "')");
1048                }
1049                if (sqlLog.isDebugEnabled()) {
1050                    sqlLog.debug("Connection " + getId() + " Executing:'" + strSQL +
1051                            "' on db '" + getDataContext() + "'");
1052                }
1053
1054                myResultSet = stmnt.executeQuery(strSQL);
1055                lastUpdateCount = stmnt.getUpdateCount();
1056            } else {
1057                if (sqlLog.isDebugEnabled()) {
1058                    sqlLog.debug("Connection " + getId() + " Executing: preparedStatement" +
1059                            " on db '" + getDataContext() + "'");
1060                }
1061                myResultSet = preparedStatement.executeQuery();
1062            }
1063
1064            long endTimer = System.currentTimeMillis();
1065            if (log.isDebugEnabled()) {
1066                String JavaDoc pre = strSQL;
1067                if (preparedStatement != null) {
1068                    pre = " prepared statement";
1069                }
1070                String JavaDoc msg = "Time to execute" + pre + " was " +
1071                        (endTimer - getLastTouched()) +
1072                        " milliseconds";
1073                log.debug(msg);
1074            }
1075            if (sqlLog.isDebugEnabled()) {
1076                String JavaDoc pre = "";
1077                if (preparedStatement != null) {
1078                    pre = " prepared statement";
1079                }
1080                String JavaDoc msg = "Time to execute" + pre + " was " +
1081                        (endTimer - getLastTouched()) +
1082                        " milliseconds";
1083                sqlLog.debug(msg);
1084            }
1085        } catch (SQLException JavaDoc se) {
1086            if (strSQL == null) {
1087                strSQL = "[Prepared Statement]";
1088            }
1089            throw new DBException("Unable to execute statement: " + strSQL +
1090                    " (" + myDescription + ", db/context '" +
1091                    getDataContext() + "')", se);
1092        }
1093    } /* execute() */
1094
1095
1096    /**
1097     * One-step execute that sets the query on the fly
1098     * NOTE: Do not use for UPDATE or DELETE, use executeUpdate instead
1099     * This method throws DBException if no result set is returned
1100     *
1101     * @param theSQL An SQL statement to be executed on the database
1102     */

1103    public synchronized void execute(String JavaDoc theSQL)
1104            throws DBException {
1105        touch();
1106        setSQL(theSQL);
1107        execute();
1108    } /* execute(String) */
1109
1110
1111    /**
1112     * One-step executeUpdate - for statements that don't return a result set
1113     * No result set is expected from this method, but the
1114     * getUpdateCount() method can be called to see how many rows were affected
1115     *
1116     * @param theSQL The SQL Statement to be executed. May be null if you're
1117     * executing a prepared statement
1118     * @throws DBException If the update fails
1119     */

1120    public synchronized void executeUpdate(String JavaDoc theSQL)
1121            throws DBException {
1122        touch();
1123
1124        if (!isConnected) {
1125            throw new DBException("Not connected - please call " +
1126                    "connect method first (" + myDescription +
1127                    ", db/context '" + getDataContext() + "')");
1128        }
1129
1130        strSQL = theSQL;
1131
1132        if (myConnection == null) {
1133            throw new DBException("Not connected (null connection) " + " (" +
1134                    myDescription + ", db/context '" +
1135                    getDataContext() + "')");
1136        }
1137
1138        checkTimeOut();
1139
1140        try {
1141            if (myResultSet != null) {
1142                try {
1143                    myResultSet.close();
1144                } catch (SQLException JavaDoc ex) {
1145                    log.warn("Error closing resultset", ex);
1146                }
1147                myResultSet = null;
1148            }
1149            if (stmnt != null) {
1150                try {
1151                    stmnt.close();
1152                } catch (SQLException JavaDoc ex) {
1153                    log.warn("Error closing stmnt");
1154                }
1155                stmnt = null;
1156            }
1157
1158            if (preparedStatement == null && strSQL != null && strSQL.length() > 0) {
1159                stmnt = myConnection.createStatement();
1160
1161                if (stmnt == null) {
1162                    throw new DBException("Null statement returned " +
1163                            "from createStatement call (" +
1164                            myDescription + ", db/context '" +
1165                            getDataContext() + "')");
1166                }
1167
1168                if (sqlLog.isDebugEnabled()) {
1169                    sqlLog.debug("Executing update:" + strSQL);
1170                }
1171                lastUpdateCount = stmnt.executeUpdate(strSQL);
1172            } else {
1173                if (sqlLog.isDebugEnabled()) {
1174                    sqlLog.debug("Executing update (prepared):");
1175                }
1176                lastUpdateCount = preparedStatement.executeUpdate();
1177            }
1178
1179            long endTimer = System.currentTimeMillis();
1180            if (log.isDebugEnabled()) {
1181                log.debug("Update '" + strSQL + "' took " +
1182                        (endTimer - getLastTouched()) +
1183                        " milliseconds");
1184            }
1185            if (sqlLog.isDebugEnabled()) {
1186                sqlLog.debug("Updated:" + lastUpdateCount + " records in " +
1187                        (endTimer - getLastTouched()) +
1188                        " milliseconds");
1189            }
1190        } catch (SQLException JavaDoc se) {
1191            String JavaDoc errMsg;
1192            if (strSQL == null) {
1193                errMsg = se.getMessage();
1194            } else {
1195                errMsg = "Unable to execute statement: " + strSQL +
1196                        "(" + myDescription + ", db/context '" +
1197                        getDataContext() + "') for reason: " + se.getMessage();
1198            }
1199            throw new DBException(errMsg, se);
1200        }
1201    } /* executeUpdate(String) */
1202
1203
1204    /**
1205     * Execute the actual store procedure in callableStatment
1206     * Store procedures method are expected to return a result
1207     * - use executeUpdate for queries that do not.
1208     *
1209     * @throws DBException If the query fails or is an update query.
1210     */

1211    public synchronized void executeProcedure()
1212            throws DBException {
1213        long beginTimer = 0;
1214        touch();
1215
1216        if (!isConnected) {
1217            throw new DBException("Not connected to database " +
1218                    "- called connect method first (" +
1219                    myDescription + ", db/context '" +
1220                    getDataContext() + "')");
1221        }
1222
1223        checkTimeOut();
1224
1225        try {
1226            if (myConnection == null) {
1227                throw new DBException("No current connection - " +
1228                        "connect to database failed: Unable to execute query:" +
1229                        "callableStatment" + " (" + myDescription +
1230                        ", db/context '" + getDataContext() + "')");
1231            }
1232
1233            //
1234
//More robust recovery. Some databases will throw a sqlexception
1235
//if the resultset or statement is already closed
1236
//
1237
if (myResultSet != null) {
1238                try {
1239                    myResultSet.close();
1240                } catch (SQLException JavaDoc ex) {
1241                    log.warn("Error closing resultset", ex);
1242                }
1243                myResultSet = null;
1244            }
1245            if (log.isDebugEnabled()) {
1246                beginTimer = System.currentTimeMillis();
1247            }
1248
1249            if (stmnt != null) {
1250                try {
1251                    stmnt.close();
1252                } catch (SQLException JavaDoc ex) {
1253                    log.warn("Error closing statement", ex);
1254                }
1255                stmnt = null;
1256            }
1257
1258
1259            //
1260
//If a callable statement has been created
1261
//then we assume we want a callable statement to execute.
1262
//
1263
if (callableStatement != null) {
1264
1265                if (sqlLog.isDebugEnabled()) {
1266                    sqlLog.debug("Connection " + getId() + " Executing: callableStatement" +
1267                            " on db '" + getDataContext() + "'");
1268                }
1269
1270// boolean hasResultSet = callableStatement.execute();
1271
myResultSet = callableStatement.executeQuery();
1272// if (hasResultSet) {
1273
// lastUpdateCount = callableStatement.getUpdateCount();
1274
// myResultSet = callableStatement.getResultSet();
1275
// }
1276
} else {
1277                throw new DBException("Unable to execute statement: callableStatment" +
1278                        " (" + myDescription + ", db/context '" +
1279                        getDataContext() + "')");
1280            }
1281
1282            if (log.isDebugEnabled()) {
1283                long endTimer = System.currentTimeMillis();
1284                log.debug("Time to execute callableStatment'" + "' was " +
1285                        (endTimer - beginTimer) +
1286                        " milliseconds");
1287            }
1288        } catch (SQLException JavaDoc se) {
1289            throw new DBException("Unable to execute statement: callableStatment" +
1290                    " (" + myDescription + ", db/context '" +
1291                    getDataContext() + "')", se);
1292        }
1293    } /* executeProcedure() */
1294
1295
1296    /**
1297     * Disconnect abandoned connections
1298     */

1299    public void finalize() {
1300        try {
1301            if (isConnected) {
1302                disconnect();
1303            }
1304        } catch (DBException de) {
1305            log.warn("Error disconconnecting connection in finalization");
1306        }
1307    } /* finalize() */
1308
1309    /**
1310     * Scroll to the first record in the result set
1311     *
1312     * @return boolean True for success, False for failure (e.g. end of set)
1313     * @throws DBException If the database connection returns an error
1314     */

1315    public synchronized boolean first()
1316            throws DBException {
1317        checkTimeOut();
1318
1319        return next();
1320    } /* first() */
1321
1322
1323    /**
1324     * Return the state of the auto-commit flag
1325     *
1326     * @return boolean True if auto-commit is enabled, false if it is not
1327     * @throws DBException If the current state of auto-commit cannot
1328     * be determined due to an invalid connection
1329     * or other database error.
1330     */

1331    public boolean getAutoCommit()
1332            throws DBException {
1333
1334        try {
1335            if (myConnection == null) {
1336                return false;
1337            } else {
1338                return myConnection.getAutoCommit();
1339            }
1340        } catch (SQLException JavaDoc se) {
1341            throw new DBException(THIS_CLASS + "setAutoCommit(boolean)" +
1342                    ":Could not get auto commit setting" + " (" +
1343                    myDescription + ")", se.getMessage());
1344        }
1345    } /* getAutoCommit() */
1346
1347
1348    /**
1349     * Return the Catalog for the current connection
1350     *
1351     * @return Catalog the name of the current catalog
1352     */

1353    public String JavaDoc getCatalog()
1354            throws DBException {
1355        try {
1356            return myConnection.getCatalog();
1357        } catch (SQLException JavaDoc se) {
1358            throw new DBException(THIS_CLASS + "getCatalog()" + ":Unable to retrieve catalog " +
1359                    " for this connection", se.getMessage());
1360        }
1361    } /* getCatalog() */
1362
1363    /**
1364     * Retrieves a BLOB object from the result set.
1365     * <p><b>Important Note:</b> Unlike any of the other data types, You must be
1366     * finished with BLOBs and CLOBs before closing the connection or moving
1367     * on to other result sets</p>
1368     *
1369     * @param fieldNum The field number [ie order in the resultset]
1370     * @return java.sql.Blob data type
1371     * @throws DBException upon error retrieving the BLOB data type.
1372     */

1373    public java.sql.Clob JavaDoc getClob(int fieldNum) throws DBException {
1374        checkTimeOut();
1375        try {
1376            return myResultSet.getClob(fieldNum);
1377        } catch (SQLException JavaDoc ex) {
1378            throw new DBException(THIS_CLASS + "getClob(int)" + ":Error fetching CLOB field " +
1379                    fieldNum + " (" + myDescription + ")",
1380                    ex.getMessage());
1381        }
1382    }
1383
1384    /**
1385     * Retrieves a BLOB object from the result set.
1386     * <p><b>Important Note:</b> Unlike any of the other data types, You must be
1387     * finished with BLOBs and CLOBs before closing the connection or moving
1388     * on to other result sets</p>
1389     *
1390     * @param fieldName The field name to retrieve
1391     * @return java.sql.Blob data type
1392     * @throws DBException upon error retrieving the BLOB data type.
1393     */

1394    public java.sql.Clob JavaDoc getClob(String JavaDoc fieldName) throws DBException {
1395        checkTimeOut();
1396        try {
1397            return myResultSet.getClob(fieldName);
1398        } catch (SQLException JavaDoc ex) {
1399            throw new DBException(THIS_CLASS + "getClob(String)" + ":Error fetching CLOB field " +
1400                    fieldName + " (" + myDescription + ")",
1401                    ex.getMessage());
1402        }
1403    }
1404
1405
1406    /**
1407     * Retrieve the time that this connection was created in System time.
1408     *
1409     * @return long integer.
1410     */

1411    public long getCreatedTime() {
1412        return this.createdTime;
1413    }
1414
1415    /**
1416     * Retrieves a BigDecimal object from the resultset
1417     *
1418     * @param fieldNum the column index
1419     * @return java.math.BigDecimal object for the field
1420     * @throws DBException upon error accessing the object
1421     */

1422    public java.math.BigDecimal JavaDoc getBigDecimal(int fieldNum) throws DBException {
1423        checkTimeOut();
1424        try {
1425            return myResultSet.getBigDecimal(fieldNum);
1426        } catch (SQLException JavaDoc se) {
1427            throw new DBException(THIS_CLASS + "getDouble(int)" + ":Error fetching double field " +
1428                    fieldNum + " (" + myDescription + ")",
1429                    se.getMessage());
1430        }
1431    }
1432
1433    /**
1434     * Retrieves a BLOB object from the result set.
1435     * <p><b>Important Note:</b> Unlike any of the other data types, You must be
1436     * finished with BLOBs and CLOBs before closing the connection or moving
1437     * on to other result sets</p>
1438     *
1439     * @param fieldNum The field number [ie order in the resultset]
1440     * @return java.sql.Blob data type
1441     * @throws DBException upon error retrieving the BLOB data type.
1442     */

1443    public java.sql.Blob JavaDoc getBlob(int fieldNum) throws DBException {
1444        checkTimeOut();
1445        try {
1446            return myResultSet.getBlob(fieldNum);
1447        } catch (SQLException JavaDoc ex) {
1448            throw new DBException(THIS_CLASS + "getBlob(int)" + ":Error fetching BLOB field " +
1449                    fieldNum + " (" + myDescription + ")",
1450                    ex.getMessage());
1451        }
1452    }
1453
1454    /**
1455     * Retrieves a BLOB object from the result set.
1456     * <p><b>Important Note:</b> Unlike any of the other data types, You must be
1457     * finished with BLOBs and CLOBs before closing the connection or moving
1458     * on to other result sets</p>
1459     *
1460     * @param fieldName The field name to retrieve
1461     * @return java.sql.Blob data type
1462     * @throws DBException upon error retrieving the BLOB data type.
1463     */

1464    public java.sql.Blob JavaDoc getBlob(String JavaDoc fieldName) throws DBException {
1465        checkTimeOut();
1466        try {
1467            return myResultSet.getBlob(fieldName);
1468        } catch (SQLException JavaDoc ex) {
1469            throw new DBException(THIS_CLASS + "getBlob(String)" + ":Error fetching BLOB field " +
1470                    fieldName + " (" + myDescription + ")",
1471                    ex.getMessage());
1472        }
1473    }
1474
1475    /**
1476     * Retrieves a Large object as a binary stream.
1477     *
1478     * @param fieldName the name of the field to retrieve
1479     * @return java.io.InputStream
1480     * @throws DBException if there's an error retrieving from the database
1481     */

1482    public java.io.InputStream JavaDoc getBinaryStream(String JavaDoc fieldName) throws DBException {
1483        checkTimeOut();
1484        try {
1485            return myResultSet.getBinaryStream(fieldName);
1486        } catch (SQLException JavaDoc ex) {
1487            throw new DBException(THIS_CLASS + "getBlob(String)" + ":Error fetching BLOB field " +
1488                    fieldName + " (" + myDescription + ")",
1489                    ex.getMessage());
1490        }
1491    }
1492
1493
1494    /**
1495     * Retrieves a Large object as a binary stream.
1496     *
1497     * @param fieldNum the number of the field to retrieve
1498     * @return java.io.InputStream
1499     * @throws DBException if there's an error retrieving from the database
1500     */

1501    public java.io.InputStream JavaDoc getBinaryStream(int fieldNum) throws DBException {
1502        checkTimeOut();
1503        try {
1504            return myResultSet.getBinaryStream(fieldNum);
1505        } catch (SQLException JavaDoc ex) {
1506            throw new DBException(THIS_CLASS + "getBlob(String)" + ":Error fetching BLOB field " +
1507                    fieldNum + " (" + myDescription + ")",
1508                    ex.getMessage());
1509        }
1510    }
1511
1512
1513    /**
1514     * Get the BLOB bytes for this particular dataset row.
1515     *
1516     * @param fieldNum The number in the row to retrieve
1517     * @return an array of bytes.
1518     * @throws DBException upon error accessing the stream
1519     */

1520    public byte[] getBytes(int fieldNum) throws DBException {
1521        checkTimeOut();
1522        try {
1523            return myResultSet.getBytes(fieldNum);
1524        } catch (SQLException JavaDoc ex) {
1525            throw new DBException("Error fetching string field " + fieldNum +
1526                    ":Last SQL was:" + strSQL + " (" +
1527                    myDescription + ")", ex.getMessage());
1528        }
1529    }
1530
1531
1532    /**
1533     * getDateTimeType allows DBObjects to ask what the correct database
1534     * type is for date/time values
1535     *
1536     * @return The date time datatype as String
1537     */

1538    public String JavaDoc getDateTimeType() {
1539        return dateTimeType;
1540    } /* getDateTimeType() */
1541
1542    /**
1543     * <p/>
1544     * Low level function that allows you to retrieve the JDBC connection associated
1545     * with this DBConnection. This allows you to do several fancy things that would
1546     * not normally happen within Expresso itself such as prepared statements, and
1547     * other low level entities. </p>
1548     * <p/>
1549     * <b>NOTE:</b> Once you grab the connection yourself, you are on your own
1550     * as far as the framework is concerned. It doesn't help you to get your
1551     * connection back in place. So, for example, if you close the connection manually,
1552     * it will mess up the connection pool. Or if you fail to free a prepared statement,
1553     * it will register as a resource leak. Be sure to restore your connection to
1554     * pristine order before releasing this DBConnection back into the pool.
1555     * </p>
1556     *
1557     * @return a java.sql.Connection JDBC connection.
1558     */

1559    public Connection JavaDoc getConnection() {
1560        if (myConnection == null) {
1561            return null;
1562        }
1563        return myConnection;
1564    }
1565
1566
1567    /**
1568     * Send back the name of the JDBC driver class being used to access
1569     * the database
1570     *
1571     * @return String The name of the driver class being used
1572     * to connect to the database.
1573     */

1574    public String JavaDoc getDBDriver() {
1575        return dbDriver;
1576    } /* getDBDriver() */
1577
1578    /**
1579     * Return the DatabaseMetaData for the connection
1580     *
1581     * @return DatabaseMetaData The meta-data object for the connection
1582     */

1583    public DatabaseMetaData JavaDoc getDBMetaData()
1584            throws DBException {
1585        try {
1586            return myConnection.getMetaData();
1587        } catch (SQLException JavaDoc se) {
1588            throw new DBException(THIS_CLASS + "getDBMetaData()" + ":Unable to retrieve meta-data " +
1589                    " for this connection", se.getMessage());
1590        }
1591    } /* getDBMetaData() */
1592
1593
1594    /**
1595     * Checks if the Database Metadata claims that this database supports
1596     * transactions.
1597     * <p/>
1598     * <i>Note:</i> Because MySQL supports tables in one database which support tranactions and
1599     * those that do not, this will return true even if the transaction is not supported.
1600     *
1601     * @return true if the database driver supports transactions. With this check
1602     * you <i>should</i> be able to call setAutoCommit(false).
1603     */

1604    public boolean supportsTransactions()
1605            throws DBException {
1606        try {
1607            return myConnection.getMetaData().supportsTransactions();
1608        } catch (SQLException JavaDoc se) {
1609            throw new DBException("Unable to retrieve meta-data " +
1610                    " for this connection", se);
1611        } catch (NullPointerException JavaDoc ex) {
1612            //This particular error can occur if getMetaData() returns null
1613
//which I've seen happen. Better to at least log it as what
1614
//happened.If
1615
log.error("NPE: Database driver didn't return connection metadata, possibly not connected", ex);
1616            return false;
1617        }
1618    }
1619
1620    /**
1621     * Return the URL field for this connection
1622     *
1623     * @return String The URL to connect to the database
1624     */

1625    public String JavaDoc getDBURL() {
1626        return dbURL;
1627    } /* getDBURL() */
1628
1629    /**
1630     * Returns the text description of this connection. When the connection
1631     * is put in use by a client program a description is set, this method
1632     * retrieves the description.
1633     *
1634     * @return String A text description of this database connection's purpose
1635     */

1636    public String JavaDoc getDescription() {
1637        return myDescription;
1638    } /* getDescription() */
1639
1640    /**
1641     * Fetch the given field of the current row as a double
1642     *
1643     * @param fieldNum The number of the field to return
1644     * @return double The double value of the given field number
1645     * @throws DBException if no such field or some other JDBC error
1646     */

1647    public double getDouble(int fieldNum)
1648            throws DBException {
1649
1650        checkTimeOut();
1651
1652        try {
1653            return myResultSet.getDouble(fieldNum);
1654        } catch (SQLException JavaDoc se) {
1655            throw new DBException(THIS_CLASS + "getDouble(int)" + ":Error fetching double field " +
1656                    fieldNum + " (" + myDescription + ")",
1657                    se.getMessage());
1658        }
1659    } /* getDouble(int) */
1660
1661
1662    /**
1663     * Get a hashtable that contains a set of field/type values
1664     * for the given table
1665     *
1666     * @param tableName Name of the table to read fields for
1667     * @return Hashtable A hashtable containing field names & types
1668     * @throws DBException If the given table cannot be scanned for
1669     * it's fields.
1670     * @deprecated Use getFieldsMap() instead
1671     */

1672    public Hashtable JavaDoc getFields(String JavaDoc tableName)
1673            throws DBException {
1674        return new Hashtable JavaDoc(getFieldsMap(tableName));
1675    } /* getFields(String) */
1676
1677
1678    /**
1679     * Gets the Escape Handler class for this connection
1680     *
1681     * @return the new <code>EscapeHandler</code> compliant interface
1682     */

1683    public synchronized EscapeHandler getEscapeHandler() {
1684        return this.escapeHandler;
1685    }
1686
1687
1688    /**
1689     * Get a hashtable that contains a set of field/type values
1690     * for the given table
1691     *
1692     * @param tableName Name of the table to read fields for
1693     * @return Hashtable A hashtable containing field names & types
1694     * @throws DBException If the given table cannot be scanned for
1695     * it's fields.
1696     */

1697    public synchronized HashMap JavaDoc getFieldsMap(String JavaDoc tableName)
1698            throws DBException {
1699        checkTimeOut();
1700
1701        HashMap JavaDoc allfields = new HashMap JavaDoc();
1702
1703        try {
1704            //Postgresql JDBC 7.2 driver bug. Tablename must be lower case
1705
//which doesn't apply to other databases such as Oracle
1706

1707            if (this.getDBDriver().equals("org.postgresql.Driver")) {
1708                tableName = tableName.toLowerCase();
1709            }
1710
1711            ResultSet JavaDoc rs = myConnection.getMetaData().getColumns("%", "%",
1712                    tableName,
1713                    "%");
1714
1715            while (rs.next()) {
1716                allfields.put(rs.getString(4), rs.getString(6));
1717            } /* while */
1718
1719        } catch (SQLException JavaDoc se) {
1720            throw new DBException(THIS_CLASS + "getFields(String)" +
1721                    ":Unable to retrieve column " +
1722                    "information (" + myDescription + ")",
1723                    se.getMessage());
1724        }
1725
1726        return allfields;
1727    } /* getFields(String) */
1728
1729
1730    /**
1731     * Get's the id of this connection. For use in the DBConnectionPool
1732     *
1733     * @return the connection id.
1734     */

1735    public int getId() {
1736        return connectionId;
1737    } /* getId() */
1738
1739    /**
1740     * Gets whether or not if this connection times out.
1741     *
1742     * @return true if this connection does not time out.
1743     */

1744    public boolean getImmortal() {
1745        return immortal;
1746    } /* getImmortal() */
1747
1748    /**
1749     * Fetch the given field of the current row as an integer
1750     *
1751     * @param fieldNum The number of the desired field
1752     * @return int The integer value of the field
1753     * @throws DBException If an error occurrs accessing the value
1754     */

1755    public int getInt(int fieldNum)
1756            throws DBException {
1757
1758        try {
1759            return myResultSet.getInt(fieldNum);
1760        } catch (SQLException JavaDoc se) {
1761            throw new DBException(THIS_CLASS + "getInt(int)" +
1762                    ":Error fetching int field " +
1763                    fieldNum + " (" + myDescription + ")",
1764                    se.getMessage());
1765        }
1766    } /* getInt(int) */
1767
1768
1769    /**
1770     * getLastTouched method is used to tell when the last time
1771     * a connection was used. This can help determine if it should
1772     * be dropped from a connection pool.
1773     *
1774     * @return Calendar Calendar object indicating the last time this
1775     * connection was actually used to communicate with the
1776     * database
1777     */

1778    public long getLastTouched() {
1779        return lastTouched;
1780    } /* getLastTouched() */
1781
1782    /**
1783     * programmatically gets the limitation optimisation insertion position
1784     * <p/>
1785     * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
1786     *
1787     * @return Integer code for the limitation position
1788     * @since Expresso 4.0
1789     */

1790    public synchronized int getLimitationPosition() {
1791        return limitationPosition;
1792    }
1793
1794    /**
1795     * programmatically sets the limitation optimisation insertion position
1796     * Called by DBConnectionPool when creating a DBConnection
1797     *
1798     * @param pos the position
1799     * @throws DBException author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
1800     * @since Expresso 4.0
1801     */

1802    synchronized void setLimitationPosition(int pos)
1803            throws DBException {
1804        this.limitationPosition = pos;
1805    }
1806
1807    /**
1808     * programmatically gets the limitation syntax string
1809     *
1810     * @return the LimitationSyntax String
1811     * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
1812     * @since Expresso 4.0
1813     */

1814    public synchronized String JavaDoc getLimitationSyntax() {
1815        return limitationSyntax;
1816    }
1817
1818    /**
1819     * programmatically gets the limitation syntax string
1820     * Usually called by DBConnectionPool when it creates the limitation
1821     * syntax
1822     *
1823     * @param syntax the new syntax
1824     * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
1825     * @since Expresso 4.0
1826     */

1827    synchronized void setLimitationSyntax(String JavaDoc syntax) {
1828        this.limitationSyntax = syntax;
1829    }
1830
1831    /**
1832     * Return the login name used to connect to the database
1833     *
1834     * @return String The login name being used to connect to the database
1835     */

1836    public String JavaDoc getLogin() {
1837        return myLogin;
1838    } /* getLogin() */
1839
1840    /**
1841     * Fetch the given field of the current row as a long
1842     *
1843     * @param fieldNum The long value of the given field number
1844     * @return long The specified field's value
1845     * @throws DBException if no such field or some other JDBC error
1846     */

1847    public long getLong(int fieldNum)
1848            throws DBException {
1849
1850        try {
1851            return myResultSet.getLong(fieldNum);
1852        } catch (SQLException JavaDoc se) {
1853            throw new DBException(THIS_CLASS + "getLong(int)" +
1854                    ":Error fetching field " +
1855                    fieldNum + " (" + myDescription + ")",
1856                    se.getMessage());
1857        }
1858    } /* getLong(int) */
1859
1860    /**
1861     * Return the ResultSetMetaData from the last executed query
1862     *
1863     * @return ResultSetMetaData The meta-data object from the last query
1864     */

1865    public synchronized ResultSetMetaData JavaDoc getMetaData() {
1866        if (myResultSet != null) {
1867            try {
1868                return myResultSet.getMetaData();
1869            } catch (SQLException JavaDoc ex) {
1870                log.error("Unable to retrieve metadata.", ex);
1871                return null;
1872            }
1873        } else {
1874            return null;
1875        }
1876    } /* getMetaData() */
1877
1878    /**
1879     * Return the password string being used to connect to the database
1880     *
1881     * @return String The password being used to connect to the database
1882     */

1883    public String JavaDoc getPassword() {
1884        return myPassword;
1885    } /* getPassword() */
1886
1887    /**
1888     * Retrieve the current result set in the connection.
1889     * <p>Like any of the lower level methods such as getConnection(), be careful
1890     * with what you do with the ResultSet or you may leave the entire Connection
1891     * Pool in an undefined state</p>
1892     * <p>You do not have to explicitly close the ResultSet when you're done
1893     * with it because DBConnectionPool.release(DBConnection) will explicitly
1894     * clear all resultsets</p>
1895     *
1896     * @return java.sql.ResultSet or possibly null if there is currently no
1897     * result set.
1898     */

1899    public ResultSet JavaDoc getResultSet() {
1900        return this.myResultSet;
1901    }
1902
1903    /**
1904     * Gets the SQL string to be executed
1905     *
1906     * @return The SQL String to be executed.
1907     */

1908    public String JavaDoc getSQL() {
1909        return strSQL;
1910    } /* getSQL() */
1911
1912    /**
1913     * Return the value in the numbered field as a string, trimming off
1914     * any trailing whitespace
1915     *
1916     * @param fieldNum The desired field number
1917     * @return String The value of the field as a string, less any trailing
1918     * whitespace
1919     * @throws DBException If the value cannot be accessed
1920     */

1921    public String JavaDoc getString(int fieldNum)
1922            throws DBException {
1923
1924        checkTimeOut();
1925
1926        if (myResultSet == null) {
1927            throw new DBException("[2]Null ResultSet object (" + myDescription + ")");
1928        }
1929        try {
1930            String JavaDoc resultValue = myResultSet.getString(fieldNum);
1931
1932            if (resultValue == null) {
1933                return null;
1934            }
1935
1936            return resultValue.trim();
1937        } catch (SQLException JavaDoc se) {
1938            if (strSQL == null) {
1939                strSQL = ("null");
1940            }
1941
1942            throw new DBException("Error fetching string field " + fieldNum + ":Last SQL was:" + strSQL + " (" +
1943                    myDescription + ")", se.getMessage());
1944        }
1945    } /* getString(int) */
1946
1947
1948    /**
1949     * Return the numbered field as a string, not trimming any trailing spaces
1950     *
1951     * @param fieldNum The number of the desired field
1952     * @return String The string field value
1953     * @throws DBException If an error occurrs accessing the given field
1954     */

1955    public String JavaDoc getStringNoTrim(int fieldNum)
1956            throws DBException {
1957        checkTimeOut();
1958
1959        if (myResultSet == null) {
1960            throw new DBException("Null ResultSet object (" + myDescription + ")");
1961        }
1962        try {
1963            String JavaDoc resultValue = myResultSet.getString(fieldNum);
1964
1965            if (resultValue == null) {
1966// return "";
1967
return null;
1968            }
1969
1970            return resultValue;
1971        } catch (SQLException JavaDoc se) {
1972            throw new DBException("Error fetching string field " + fieldNum + ":Last SQL was:" + strSQL + " (" +
1973                    " (" + myDescription + ")", se.getMessage());
1974        }
1975    } /* getStringNoTrim(int) */
1976
1977
1978    /**
1979     * Return the value in the named field as a string, trimming off
1980     * any trailing whitespace
1981     *
1982     * @param fieldName The desired column name
1983     * @return String The value of the field as a string, less any trailing
1984     * whitespace
1985     * @throws DBException If the value cannot be accessed
1986     */

1987    public String JavaDoc getString(String JavaDoc fieldName)
1988            throws DBException {
1989
1990        String JavaDoc resultValue = getStringNoTrim(fieldName);
1991
1992        if (resultValue == null) {
1993            return null;
1994        }
1995
1996        return resultValue.trim();
1997    } /* getString(String) */
1998
1999
2000    /**
2001     * Return the value in the named field as a string
2002     *
2003     * @param fieldName The desired column name
2004     * @return String The value of the field as a string, less any trailing
2005     * whitespace
2006     * @throws DBException If the value cannot be accessed
2007     */

2008    public String JavaDoc getStringNoTrim(String JavaDoc fieldName)
2009            throws DBException {
2010        checkTimeOut();
2011
2012        if (myResultSet == null) {
2013            throw new DBException("[2]Null ResultSet object (" + myDescription + ")");
2014        }
2015        try {
2016            String JavaDoc resultValue = myResultSet.getString(fieldName);
2017
2018            if (resultValue == null) {
2019                return null;
2020            }
2021
2022            return resultValue;
2023        } catch (SQLException JavaDoc se) {
2024            if (strSQL == null) {
2025                strSQL = ("null");
2026            }
2027
2028            throw new DBException("Error fetching string field " + fieldName + ":Last SQL was:" + strSQL + " (" +
2029                    myDescription + ")", se.getMessage());
2030        }
2031    } /* getStringNoTrim(String) */
2032
2033
2034    /**
2035     * Return the value in the named field as a string, trimming off
2036     * any trailing whitespace
2037     *
2038     * @param fieldName The desired column name
2039     * @return Date The value of the field as a Date format
2040     * @throws DBException If the value cannot be accessed
2041     * author Yves Henri AMAIZO
2042     * @since Expresso 5.0
2043     */

2044    public Date JavaDoc getTimestamp(String JavaDoc fieldName)
2045            throws DBException {
2046        checkTimeOut();
2047
2048        if (myResultSet == null) {
2049            throw new DBException("[2]Null ResultSet object (" +
2050                    myDescription + ")");
2051        }
2052        try {
2053            Date JavaDoc resultValue = myResultSet.getTimestamp(fieldName);
2054
2055            return resultValue;
2056        } catch (SQLException JavaDoc se) {
2057            if (strSQL == null) {
2058                strSQL = ("null");
2059            }
2060
2061            throw new DBException("Error fetching string field " + fieldName +
2062                    ":Last SQL was:" + strSQL + " (" +
2063                    myDescription + ")", se.getMessage());
2064        }
2065    } /* getTimestamp(String) */
2066
2067
2068    /**
2069     * Return the value in the named field as a string, trimming off
2070     * any trailing whitespace
2071     *
2072     * @param fieldNum The desired column number
2073     * @return Date The value of the field as a Date format
2074     * @throws DBException If the value cannot be accessed
2075     * author Yves Henri AMAIZO
2076     * @since Expresso 5.0
2077     */

2078    public Date JavaDoc getTimestamp(int fieldNum)
2079            throws DBException {
2080        checkTimeOut();
2081
2082        if (myResultSet == null) {
2083            throw new DBException("[2]Null ResultSet object (" +
2084                    myDescription + ")");
2085        }
2086        try {
2087            Date JavaDoc resultValue = myResultSet.getTimestamp(fieldNum);
2088
2089            return resultValue;
2090        } catch (SQLException JavaDoc se) {
2091            if (strSQL == null) {
2092                strSQL = ("null");
2093            }
2094
2095            throw new DBException("Error fetching string field " + fieldNum +
2096                    ":Last SQL was:" + strSQL + " (" +
2097                    myDescription + ")", se.getMessage());
2098        }
2099    } /* getTimestamp(int) */
2100
2101
2102    /**
2103     * Return the value in the named field as a string, trimming off
2104     * any trailing whitespace
2105     *
2106     * @param fieldName The desired column name
2107     * @return Date The value of the field as a Time format
2108     * @throws DBException If the value cannot be accessed
2109     * author Yves Henri AMAIZO
2110     * @since Expresso 5.0
2111     */

2112    public Date JavaDoc getTime(String JavaDoc fieldName)
2113            throws DBException {
2114        checkTimeOut();
2115
2116        if (myResultSet == null) {
2117            throw new DBException("[2]Null ResultSet object (" +
2118                    myDescription + ")");
2119        }
2120        try {
2121            Date JavaDoc resultValue = myResultSet.getTime(fieldName);
2122
2123            return resultValue;
2124        } catch (SQLException JavaDoc se) {
2125            if (strSQL == null) {
2126                strSQL = ("null");
2127            }
2128
2129            throw new DBException("Error fetching string field " + fieldName +
2130                    ":Last SQL was:" + strSQL + " (" +
2131                    myDescription + ")", se.getMessage());
2132        }
2133    } /* getTime(String) */
2134
2135
2136    /**
2137     * Return the value in the named field as a string, trimming off
2138     * any trailing whitespace
2139     *
2140     * @param fieldNum The desired column number
2141     * @return Date The value of the field as a Time format
2142     * @throws DBException If the value cannot be accessed
2143     * author Yves Henri AMAIZO
2144     * @since Expresso 5.0
2145     */

2146    public Date JavaDoc getTime(int fieldNum)
2147            throws DBException {
2148        checkTimeOut();
2149
2150        if (myResultSet == null) {
2151            throw new DBException("[2]Null ResultSet object (" +
2152                    myDescription + ")");
2153        }
2154        try {
2155            Date JavaDoc resultValue = myResultSet.getTime(fieldNum);
2156
2157            return resultValue;
2158        } catch (SQLException JavaDoc se) {
2159            if (strSQL == null) {
2160                strSQL = ("null");
2161            }
2162
2163            throw new DBException("Error fetching string field " + fieldNum +
2164                    ":Last SQL was:" + strSQL + " (" +
2165                    myDescription + ")", se.getMessage());
2166        }
2167    } /* getTime(int) */
2168
2169
2170    /**
2171     * Return the value in the named field as a string, trimming off
2172     * any trailing whitespace
2173     *
2174     * @param fieldName The desired column name
2175     * @return Date The value of the field as a Time format
2176     * @throws DBException If the value cannot be accessed
2177     * author Yves Henri AMAIZO
2178     * @since Expresso 5.0
2179     */

2180    public Date JavaDoc getDate(String JavaDoc fieldName)
2181            throws DBException {
2182        checkTimeOut();
2183
2184        if (myResultSet == null) {
2185            throw new DBException("[2]Null ResultSet object (" +
2186                    myDescription + ")");
2187        }
2188        try {
2189            Date JavaDoc resultValue = myResultSet.getDate(fieldName);
2190
2191            return resultValue;
2192        } catch (SQLException JavaDoc se) {
2193            if (strSQL == null) {
2194                strSQL = ("null");
2195            }
2196
2197            throw new DBException("Error fetching string field " + fieldName +
2198                    ":Last SQL was:" + strSQL + " (" +
2199                    myDescription + ")", se.getMessage());
2200        }
2201    } /* getDate(String) */
2202
2203
2204    /**
2205     * Return the value in the named field as a string, trimming off
2206     * any trailing whitespace
2207     *
2208     * @param fieldNum The desired column name
2209     * @return Date The value of the field as a Time format
2210     * @throws DBException If the value cannot be accessed
2211     * author Yves Henri AMAIZO
2212     * @since Expresso 5.0
2213     */

2214    public Date JavaDoc getDate(int fieldNum)
2215            throws DBException {
2216        checkTimeOut();
2217
2218        if (myResultSet == null) {
2219            throw new DBException("[2]Null ResultSet object (" +
2220                    myDescription + ")");
2221        }
2222        try {
2223            Date JavaDoc resultValue = myResultSet.getDate(fieldNum);
2224
2225            return resultValue;
2226        } catch (SQLException JavaDoc se) {
2227            if (strSQL == null) {
2228                strSQL = "null";
2229            }
2230
2231            throw new DBException("Error fetching string field " + fieldNum +
2232                    ":Last SQL was:" + strSQL + " (" +
2233                    myDescription + ")", se.getMessage());
2234        }
2235    } /* getDate(int) */
2236
2237
2238    /**
2239     * Attempt to return a mapping of java.sql.Type types to actual type names
2240     * used by this database. If we encounter
2241     * any error doing this, simply return an empty hashtable
2242     *
2243     * @return a Hashtable of the type map.
2244     */

2245    public Hashtable JavaDoc getTypeMap() {
2246        try {
2247            DatabaseMetaData JavaDoc dm = myConnection.getMetaData();
2248            ResultSet JavaDoc rsx = dm.getTypeInfo();
2249            Hashtable JavaDoc theMap = new Hashtable JavaDoc(3);
2250            String JavaDoc oneTypeString = null;
2251            int oneTypeInt = 0;
2252
2253            while (rsx.next()) {
2254                oneTypeString = rsx.getString(1);
2255                oneTypeInt = rsx.getShort(2);
2256                theMap.put(oneTypeString, new Integer JavaDoc(oneTypeInt));
2257            }
2258
2259            return theMap;
2260        } catch (Exception JavaDoc se) {
2261            return new Hashtable JavaDoc();
2262        }
2263    } /* getTypeMap() */
2264
2265    /**
2266     * Returns the number of rows affected by the last operation .
2267     * Only useful after an executeUpdate
2268     *
2269     * @return int: The integer count of the number of rows affected
2270     */

2271    public int getUpdateCount() {
2272        return lastUpdateCount;
2273    } /* getUpdateCount() */
2274
2275    /**
2276     * Return a vector of wild card characters for this database type.
2277     * This can be used to determine if the search criteria supplied by a
2278     * user has wild-card characters in it or is an exact match
2279     *
2280     * @return Enumeration A list of the wild-card characters used by
2281     * this database connection
2282     * @deprecated 9/04, v5.5+ use DBConnectionPool.getDefaultWildCards() instead
2283     */

2284    public Enumeration JavaDoc getWildCards() {
2285        Vector JavaDoc newChars = new Vector JavaDoc(4);
2286        newChars.addElement(("%"));
2287        newChars.addElement(("_"));
2288        newChars.addElement(("["));
2289        newChars.addElement(("]"));
2290
2291        return newChars.elements();
2292    } /* getWildCards() */
2293
2294    /**
2295     * Return a vector of wild card characters for this database type.
2296     * This can be used to determine if the search criteria supplied by a
2297     * user has wild-card characters in it or is an exact match.
2298     *
2299     * @return A list of the wild-card characters used by
2300     * this database connection
2301     * @deprecated 9/04, v5.5+ use DBConnectionPool.getDefaultWildCards() instead
2302     */

2303    public ArrayList JavaDoc getWildCardsList() {
2304        ArrayList JavaDoc newChars = new ArrayList JavaDoc(4);
2305        newChars.add(("%"));
2306        newChars.add(("_"));
2307        newChars.add(("["));
2308        newChars.add(("]"));
2309
2310        return newChars;
2311    }
2312
2313    /**
2314     * Return the Database current transaction mode set.
2315     * <p/>
2316     * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
2317     *
2318     * @return Expresso corrresponding values.
2319     * @since Expresso 5.3
2320     */

2321    public int getTransactionMode()
2322            throws DBException {
2323        try {
2324            int transactionMode = myConnection.getTransactionIsolation();
2325            switch (transactionMode) {
2326                case Connection.TRANSACTION_NONE:
2327                    return 0;
2328                case Connection.TRANSACTION_READ_COMMITTED:
2329                    return transactionCommittedMode;
2330                case Connection.TRANSACTION_READ_UNCOMMITTED:
2331                    return transactionUncommittedMode;
2332                case Connection.TRANSACTION_REPEATABLE_READ:
2333                    return transactionRepeatableMode;
2334                case Connection.TRANSACTION_SERIALIZABLE:
2335                    return transactionSerializableMode;
2336            }
2337        } catch (SQLException JavaDoc se) {
2338            throw new DBException("Unable to retrieve transaction mode set " +
2339                    " for this connection", se);
2340        }
2341        return -1;
2342    }
2343
2344
2345    /**
2346     * When this connection is used as part of a pool of connections,
2347     * tell whether or not it is available to be re-allocated
2348     *
2349     * @return boolean True if the connection is available for use,
2350     * false if it is in use already
2351     */

2352    public boolean isAvailable() {
2353        return currentAvailable;
2354    } /* isAvailable() */
2355
2356    /**
2357     * When this connection has lost its connection to the server,
2358     * tell whether or not it is available to be re-allocated
2359     *
2360     * @return boolean True if the connection has been lost,
2361     * false if it is still usable
2362     */

2363    public boolean isClosed()
2364            throws DBException {
2365
2366        try {
2367            return myConnection.isClosed();
2368        } catch (SQLException JavaDoc se) {
2369            throw new DBException(THIS_CLASS + "isClosed()" + ":Cannot access connection to " +
2370                    "database via (driver or JNDI) '" + dbDriver +
2371                    "' and URL '" + dbURL + "' (" +
2372                    myDescription + ")", se.getMessage());
2373        }
2374    } /* isClosed() */
2375
2376
2377    /**
2378     * Scroll to the next record in the result set
2379     *
2380     * @return boolean: true if scrolled successfully, false if end of
2381     * record set
2382     * @throws DBException If a JDBC error occurred while scrolling
2383     */

2384    public synchronized boolean next()
2385            throws DBException {
2386        touch();
2387        checkTimeOut();
2388        try {
2389            if (myResultSet == null) {
2390                throw new DBException(THIS_CLASS + "next()" +
2391                        ":No result set established - " +
2392                        "cannot select next record for statement '" +
2393                        strSQL + "'");
2394            }
2395            if (!myResultSet.next()) {
2396                /* Hit the end of file */
2397                return false;
2398            }
2399            return true;
2400        } catch (SQLException JavaDoc se) {
2401            throw new DBException(THIS_CLASS + "next()" + ":Error retrieving next row for " +
2402                    "statement " + strSQL + " (" +
2403                    myDescription + ")", se.getMessage());
2404        }
2405    } /* next() */
2406
2407
2408    /**
2409     * Roll back the current transaction, as if it were never requested. If
2410     * the JDBC driver claims it doesn't support transactions, then this
2411     * method is a NOOP except for touching the connection
2412     *
2413     * @throws DBException If the rollback encounters an error
2414     */

2415    public synchronized void rollback()
2416            throws DBException {
2417        if (this.supportsTransactions()) {
2418            try {
2419                myConnection.rollback();
2420            } catch (SQLException JavaDoc se) {
2421                throw new DBException(THIS_CLASS + "rollback()" + ":Could not rollback" + " (" +
2422                        myDescription + ")", se.getMessage());
2423            }
2424        }
2425
2426        touch();
2427    } /* rollback() */
2428
2429
2430    /**
2431     * Set auto-commit on or off for this connection. If auto-commit is on, each
2432     * statement is immediately written to the database and cannot be
2433     * rolled back
2434     *
2435     * @param b True to enable auto-commit, false to disable it
2436     * @throws DBException upon error
2437     */

2438    public synchronized void setAutoCommit(boolean b)
2439            throws DBException {
2440        if (this.supportsTransactions()) {
2441            try {
2442                myConnection.setAutoCommit(b);
2443            } catch (SQLException JavaDoc se) {
2444                throw new DBException(THIS_CLASS + "setAutoCommit(boolean)" +
2445                        ":Could not set auto commit" +
2446                        " (" + myDescription + ")", se.getMessage());
2447            }
2448        }
2449        touch();
2450    } /* setAutoCommit(boolean) */
2451
2452
2453    /**
2454     * When this connection is used as part of a pool of connections,
2455     * tell whether or not it is available to be re-allocated
2456     *
2457     * @param newAvailable Boolean indicating the connection is
2458     * available (true) or not (false)
2459     */

2460    public synchronized void setAvailable(boolean newAvailable) {
2461        currentAvailable = newAvailable;
2462        touch();
2463    } /* setAvailable(boolean) */
2464
2465    /**
2466     * setDateTimeType method allows the default database type of "datetime"
2467     * to be overridden for databases where this is not the type for date
2468     * and time values (e.g. Oracle). The value supplied is used
2469     * for the database type for any "datetime" create statements
2470     *
2471     * @param newDateTimeType The data type used to store date/time values
2472     * in this particular type of database
2473     * @throws DBException upon error
2474     */

2475    public synchronized void setDateTimeType(String JavaDoc newDateTimeType)
2476            throws DBException {
2477        if (newDateTimeType == null) {
2478            newDateTimeType = ("");
2479        }
2480        if (!newDateTimeType.equals("")) {
2481            dateTimeType = newDateTimeType;
2482        } else {
2483            throw new DBException(THIS_CLASS + "setDateTimeType(String)" +
2484                    ":date/time type for database " +
2485                    " must not be blank");
2486        }
2487    } /* setDateTimeType(String) */
2488
2489
2490    /**
2491     * Set a description for this database connection. When status is requested
2492     * from the connection pool, this is used to describe the connection.
2493     * Any client requesting a connection from the pool should set the
2494     * description of the connection as soon as it's returned
2495     *
2496     * @param newDescription Description of this connection
2497     */

2498    public synchronized void setDescription(String JavaDoc newDescription) {
2499        if (newDescription != null) {
2500            myDescription = newDescription;
2501        }
2502
2503        touch();
2504    } /* setDescription(String) */
2505
2506    /**
2507     * Sets the connection ID number for this object Only accessable from
2508     * DBConnectionPool
2509     *
2510     * @param newId The new connection id number
2511     */

2512    synchronized void setId(int newId) {
2513        connectionId = newId;
2514    } /* setId(int) */
2515
2516    /**
2517     * Sets this connection to be immortal, ie it never gets removed or
2518     * disconnected
2519     *
2520     * @param newImmortal The new value to set it to.
2521     */

2522    public synchronized void setImmortal(boolean newImmortal) {
2523        immortal = newImmortal;
2524    } /* setImmortal(boolean) */
2525
2526    /**
2527     * Set the SQL to be run against the database
2528     *
2529     * @param sqlStatement The SQL statement to be run
2530     */

2531    public synchronized void setSQL(String JavaDoc sqlStatement) {
2532        strSQL = sqlStatement;
2533    } /* setSQL(String) */
2534
2535    /**
2536     * Sets the Escape Handler class for this connection
2537     *
2538     * @param newValue the new <code>EscapeHandler</code> compliant interface
2539     */

2540    public synchronized void setEscapeHandler(EscapeHandler newValue) {
2541        this.escapeHandler = newValue;
2542    }
2543
2544
2545    /**
2546     * Update the last touched date/time for this connection
2547     */

2548    public synchronized void touch() {
2549        lastTouched = System.currentTimeMillis();
2550    } /* touch() */
2551
2552
2553    /**
2554     * Sets the data context for the connection.
2555     *
2556     * @param newDBName the datacontext name to use
2557     */

2558    public synchronized void setDBName(String JavaDoc newDBName) {
2559        this.setDataContext(newDBName);
2560    }
2561
2562    /**
2563     * Sets the data context for the connection.
2564     *
2565     * @param newDBName the datacontext name to use
2566     */

2567    public synchronized void setDataContext(String JavaDoc newDBName) {
2568        if (StringUtil.notNull(newDBName).length() == 0) {
2569            dbName = DEFAULT_DB_CONTEXT_NAME;
2570        } else {
2571            dbName = newDBName;
2572        }
2573    }
2574
2575    /**
2576     * Retrieve the data context name we're associated with
2577     *
2578     * @return java.lang.String of the current data Context
2579     */

2580    public String JavaDoc getDataContext() {
2581        return dbName;
2582    }
2583
2584    /**
2585     * Retrieve what DBConnectionPool 'owns' this pool
2586     *
2587     * @return DBConnectionPool (may be null if nobody owns this object)
2588     */

2589    public DBConnectionPool getParentPool() {
2590        return parentPool;
2591    }
2592
2593    /**
2594     * Sets the parentPool... this is done by the DBConnecitonPool object.
2595     *
2596     * @param newParentPool the DBConnectionPool that created this connection.
2597     */

2598    public void setParentPool(DBConnectionPool newParentPool) {
2599        this.parentPool = newParentPool;
2600    }
2601
2602    /**
2603     * <p>Releases the DBConnection back into the parent DBConnectionPool. Allows
2604     * for syntax like:</p>
2605     * <code>
2606     * <p/>
2607     * DBConnection connection = DBConnectionPool.getInstance("default").getConnection(); <br/>
2608     * [do stuff]<br />
2609     * connection.release(); <br />
2610     * </code>
2611     * </p>
2612     */

2613    public synchronized void release() {
2614        DBConnectionPool parent = getParentPool();
2615        if (parent != null) {
2616            parent.release(this);
2617        } else {
2618            log.warn("No parent connection pool defined for this DBConnection");
2619        }
2620
2621    }
2622
2623    public JNDIConfig getJNDIConfig(JDBCConfig curConfig) {
2624        if (curConfig instanceof com.jcorporate.expresso.core.misc.ConfigJdbc) {
2625            return ((com.jcorporate.expresso.core.misc.ConfigJdbc) curConfig).getMyJndi();
2626        } else {
2627            return null;
2628        }
2629    }
2630
2631    /**
2632     * Returns the name of the currently set DataContext
2633     *
2634     * @return java.lang.String
2635     */

2636    public String JavaDoc getDBName() {
2637        return this.getDataContext();
2638    }
2639
2640
2641    /**
2642     * Set Database transaction isolation mode.
2643     * <p/>
2644     * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
2645     *
2646     * @since Expresso 5.3
2647     */

2648    public void setTransactionIsolation(int isolationMode)
2649            throws DBException {
2650        try {
2651            if (supportsTransactions()) {
2652                myConnection.setTransactionIsolation(isolationMode);
2653            }
2654        } catch (SQLException JavaDoc se) {
2655            throw new DBException("Unable to set Database transaction isolation mode set " +
2656                    " for this connection", se);
2657        }
2658    }
2659
2660    /**
2661     * Set EXPRESSO transaction mode for the current DBConnection.
2662     * <p/>
2663     * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
2664     *
2665     * @since Expresso 5.3
2666     */

2667    public void setTransactionMode(int transactionMode) throws DBException {
2668
2669        try {
2670            switch (transactionMode) {
2671                case TRANSACTION_NORMAL_MODE:
2672                    setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
2673                    break;
2674                case TRANSACTION_DIRTY_MODE:
2675                    setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
2676                    break;
2677                case TRANSACTION_RESTRICTIVE_MODE:
2678                    setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
2679                    break;
2680                case TRANSACTION_EXCLUSIVE_MODE:
2681                    setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
2682                    break;
2683                default:
2684                    throw new IllegalArgumentException JavaDoc("Unknown transaction mode: " + transactionMode);
2685            }
2686        } catch (DBException se) {
2687            throw new DBException("", se);
2688        }
2689    }
2690
2691    /**
2692     * Set EXPRESSO transaction mode for the current DBConnection.
2693     * <p/>
2694     * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
2695     *
2696     * @since Expresso 5.3
2697     */

2698    public void setTransactionCommittedMode() throws DBException {
2699
2700        try {
2701            setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
2702        } catch (DBException se) {
2703            throw new DBException("", se);
2704        }
2705    }
2706
2707    /**
2708     * Set EXPRESSO transaction mode for the current DBConnection.
2709     * <p/>
2710     * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
2711     *
2712     * @since Expresso 5.3
2713     */

2714    public void setTransactionUncommittedMode() throws DBException {
2715
2716        try {
2717            setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
2718        } catch (DBException se) {
2719            throw new DBException("", se);
2720        }
2721    }
2722
2723    /**
2724     * Set EXPRESSO transaction mode for the current DBConnection.
2725     * <p/>
2726     * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
2727     *
2728     * @since Expresso 5.3
2729     */

2730    public void setTransactionRepeatableMode() throws DBException {
2731
2732        try {
2733            setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
2734        } catch (DBException se) {
2735            throw new DBException("", se);
2736        }
2737    }
2738
2739    /**
2740     * Set EXPRESSO transaction mode for the current DBConnection.
2741     * <p/>
2742     * author Yves Henri AMAIZO, Mon Dec 22 10:30:59 2003
2743     *
2744     * @since Expresso 5.3
2745     */

2746    public void setTransactionSerializableMode() throws DBException {
2747
2748        try {
2749            setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
2750        } catch (DBException se) {
2751            throw new DBException("", se);
2752        }
2753    }
2754
2755    /**
2756     * Trim or not trim parameter set for this connection
2757     *
2758     * @return boolean True if the connection not trim the persistence string.
2759     * false if the persistence string will have to be trimmed
2760     */

2761    public boolean isStringNotTrim() {
2762        return myJdbc.isStringNotTrim();
2763    } /* isStringNotTrimmed() */
2764
2765    /**
2766     * Trim or not trim parameter set for this connection
2767     *
2768     * @return boolean True if the connection not trim the persistence string.
2769     * false if the persistence string will have to be trimmed
2770     */

2771    public boolean isTransactionNotActive() {
2772        return myJdbc.isTransactionNotActive();
2773    } /* isTransactionNotActive() */
2774
2775
2776    /**
2777     * @param config
2778     */

2779    public void setJDBCCondig(JDBCConfig config) {
2780        myJdbc = config;
2781    }
2782
2783}
2784
2785/* DBConnection */
2786
Popular Tags