0001: /*
0002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
0003: * Distributed under the terms of either:
0004: * - the common development and distribution license (CDDL), v1.0; or
0005: * - the GNU Lesser General Public License, v2.1 or later
0006: * $Id: DbQueryManager.java 3784 2007-06-11 16:44:35Z gbevin $
0007: */
0008: package com.uwyn.rife.database;
0009:
0010: import com.uwyn.rife.database.exceptions.DatabaseException;
0011: import com.uwyn.rife.database.exceptions.RollbackException;
0012: import com.uwyn.rife.database.exceptions.RowProcessorErrorException;
0013: import com.uwyn.rife.database.queries.Query;
0014: import com.uwyn.rife.database.queries.ReadQuery;
0015: import com.uwyn.rife.tools.ExceptionUtils;
0016: import com.uwyn.rife.tools.InnerClassException;
0017: import com.uwyn.rife.tools.InputStreamUser;
0018: import com.uwyn.rife.tools.ReaderUser;
0019: import com.uwyn.rife.tools.exceptions.ControlFlowRuntimeException;
0020: import java.io.IOException;
0021: import java.io.InputStream;
0022: import java.io.Reader;
0023: import java.sql.ResultSet;
0024: import java.sql.SQLException;
0025: import java.util.Calendar;
0026: import java.util.List;
0027: import java.util.logging.Logger;
0028:
0029: /**
0030: * This is a convenience class to make it easy to control the queries that
0031: * handle the retrieval, storage, update and removal of data in a database.
0032: * All queries will be executed in a connection of the <code>Datasource</code>
0033: * that's provided to the constructor of the <code>DbQueryManager</code>.
0034: * <p>A collection of convenience methods have been provided to quickly
0035: * execute queries in a variety of manners without having to worry about the
0036: * logic behind it or having to remember to close the queries at the
0037: * appropriate moment. These methods optionally interact with the
0038: * <code>DbPreparedStatementHandler</code> and <code>DbResultSetHandler</code>
0039: * classes to make it possible to fully customize the executed queries. The
0040: * following categories of worry-free methods exist:
0041: * <ul>
0042: * <li>{@linkplain #executeUpdate(Query) execute an update query directly}
0043: * <li>{@linkplain #executeUpdate(Query,DbPreparedStatementHandler) execute a
0044: * customizable update query}
0045: * <li>{@linkplain #executeQuery(ReadQuery,DbPreparedStatementHandler) execute a
0046: * customizable select query}
0047: * <li>{@linkplain #executeHasResultRows(ReadQuery,DbPreparedStatementHandler)
0048: * check the result rows of a customizable select query}
0049: * <li>{@linkplain #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
0050: * obtain the first value of a customizable select query}
0051: * <li>{@linkplain
0052: * #executeFetchFirst(ReadQuery,DbRowProcessor,DbPreparedStatementHandler) fetch
0053: * the first row of a customizable select query}
0054: * <li>{@linkplain
0055: * #executeFetchFirstBean(ReadQuery,Class,DbPreparedStatementHandler) fetch the
0056: * first bean of a customizable select query}
0057: * <li>{@linkplain
0058: * #executeFetchAll(ReadQuery,DbRowProcessor,DbPreparedStatementHandler) fetch
0059: * all rows of a customizable select query}
0060: * <li>{@linkplain
0061: * #executeFetchAllBeans(ReadQuery,Class,DbPreparedStatementHandler) fetch all
0062: * beans of a customizable select query}
0063: * </ul>
0064: * <p>Lower-level methods are also available for the sake of repetitive
0065: * code-reduction. To obtain execute regular statements directly,
0066: * use the {@link #executeQuery(ReadQuery) executeQuery} method.
0067: * <p>Finally, <code>since DbStatement</code> and
0068: * <code>DbPreparedStatement</code> instances preserve a reference to their
0069: * resultset, it's easy to iterate over the rows of a resultset with the
0070: * {@link #fetch(ResultSet,DbRowProcessor) fetch} or {@link
0071: * #fetchAll(ResultSet,DbRowProcessor) fetchAll} methods.
0072: *
0073: * @author Geert Bevin (gbevin[remove] at uwyn dot com)
0074: * @version $Revision: 3784 $
0075: * @see com.uwyn.rife.database.DbPreparedStatement
0076: * @see com.uwyn.rife.database.DbStatement
0077: * @see com.uwyn.rife.database.DbRowProcessor
0078: * @see com.uwyn.rife.database.DbPreparedStatementHandler
0079: * @see com.uwyn.rife.database.DbResultSetHandler
0080: * @see com.uwyn.rife.database.DbConnectionUser
0081: * @since 1.0
0082: */
0083: public class DbQueryManager implements Cloneable {
0084: private final Datasource mDatasource;
0085:
0086: /**
0087: * Instantiates a new <code>DbQueryManager</code> object and ties it to
0088: * the provided datasource.
0089: *
0090: * @param datasource the datasource that will be used to obtain database
0091: * connections from
0092: * @since 1.0
0093: */
0094: public DbQueryManager(Datasource datasource) {
0095: if (null == datasource)
0096: throw new IllegalArgumentException(
0097: "datasource can't be null.");
0098:
0099: mDatasource = datasource;
0100: }
0101:
0102: /**
0103: * Safely and quickly executes an update statement. It relies on the
0104: * wrapped {@link DbStatement#executeUpdate(String)} method, but also
0105: * automatically closes the statement after its execution.
0106: * <p>This method is typically used in situations where one static update
0107: * query needs to be executed without any parametrization or other
0108: * processing.
0109: * <h3>Example</h3>
0110: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
0111: *int count = manager.executeUpdate("INSERT INTO person (name) VALUES ('me')");</pre>
0112: *
0113: * @param sql the sql query that has to be executed
0114: * @return the row count for the executed query
0115: * @exception DatabaseException see {@link
0116: * DbStatement#executeUpdate(String)}
0117: * @see DbStatement#executeUpdate(String)
0118: * @see #executeUpdate(Query)
0119: * @since 1.0
0120: */
0121: public int executeUpdate(String sql) throws DatabaseException {
0122: if (null == sql)
0123: throw new IllegalArgumentException("sql can't be null.");
0124:
0125: DbConnection connection = getConnection();
0126: try {
0127: DbStatement statement = connection.createStatement();
0128: try {
0129: return statement.executeUpdate(sql);
0130: } finally {
0131: defensiveClose(statement);
0132: }
0133: } finally {
0134: connection.close();
0135: }
0136: }
0137:
0138: /**
0139: * Safely and quickly executes an update statement. It relies on the
0140: * wrapped {@link DbStatement#executeUpdate(Query)} method, but also
0141: * automatically closes the statement after its execution.
0142: * <p>This method is typically used in situations where one static update
0143: * query needs to be executed without any parametrization or other
0144: * processing.
0145: * <h3>Example</h3>
0146: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
0147: *Insert insert = new Insert(datasource);
0148: *insert.into("person").field("name", "me");
0149: *int count = manager.executeUpdate(insert);</pre>
0150: *
0151: * @param query the query builder instance that needs to be executed
0152: * @return the row count for the executed query
0153: * @exception DatabaseException see {@link
0154: * DbStatement#executeUpdate(Query)}
0155: * @see DbStatement#executeUpdate(Query)
0156: * @see #executeUpdate(String)
0157: * @since 1.0
0158: */
0159: public int executeUpdate(Query query) throws DatabaseException {
0160: if (null == query)
0161: throw new IllegalArgumentException("query can't be null.");
0162:
0163: DbConnection connection = getConnection();
0164: try {
0165: DbStatement statement = connection.createStatement();
0166: try {
0167: return statement.executeUpdate(query);
0168: } finally {
0169: defensiveClose(statement);
0170: }
0171: } finally {
0172: connection.close();
0173: }
0174: }
0175:
0176: private DbPreparedStatement getPreparedStatement(Query query,
0177: DbResultSetHandler handler, DbConnection connection) {
0178: return mDatasource
0179: .getCapabilitiesCompensator()
0180: .getCapablePreparedStatement(query, handler, connection);
0181: }
0182:
0183: private void executeQuery(DbPreparedStatement statement,
0184: DbPreparedStatementHandler handler) {
0185: if (null == handler) {
0186: statement.executeQuery();
0187: } else {
0188: handler.performQuery(statement);
0189: }
0190: }
0191:
0192: private DbResultSet getResultSet(DbPreparedStatement statement) {
0193: return mDatasource.getCapabilitiesCompensator()
0194: .getCapableResultSet(statement);
0195: }
0196:
0197: /**
0198: * Safely execute an updates statement. It relies on the wrapped {@link
0199: * DbPreparedStatement#executeUpdate()} method, but also automatically
0200: * closes the statement after its execution and allows customization of
0201: * the prepared statement through an optional instance of {@link
0202: * DbPreparedStatementHandler}.
0203: * <p>This method is typically used when you need to fully customize a
0204: * query at runtime, but still want to benefit of a safety net that
0205: * ensures that the allocated statement will be closed.
0206: * <h3>Example</h3>
0207: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
0208: *Insert insert = new Insert(datasource);
0209: *insert.into("person").fieldParameter("name");
0210: *final String name = "me";
0211: *int count = manager.executeUpdate(insert, new DbPreparedStatementHandler() {
0212: * public void setParameters(DbPreparedStatement statement)
0213: * {
0214: * statement
0215: * .setString("name", name);
0216: * }
0217: * });</pre>
0218: *
0219: * @param query the query builder instance that needs to be executed
0220: * @param handler an instance of <code>DbPreparedStatementHandler</code>
0221: * that will be used to customize the query execution; or
0222: * <code>null</code> if you don't want to customize it at all
0223: * @return the row count for the executed query
0224: * @exception DatabaseException see {@link
0225: * DbPreparedStatement#executeUpdate()}
0226: * @see DbPreparedStatement#executeUpdate()
0227: * @see DbPreparedStatementHandler
0228: * @since 1.0
0229: */
0230: public int executeUpdate(Query query,
0231: DbPreparedStatementHandler handler)
0232: throws DatabaseException {
0233: if (null == query)
0234: throw new IllegalArgumentException("query can't be null.");
0235:
0236: DbConnection connection = getConnection();
0237: try {
0238: DbPreparedStatement statement = getPreparedStatement(query,
0239: handler, connection);
0240: try {
0241: if (null == handler) {
0242: return statement.executeUpdate();
0243: }
0244:
0245: return handler.performUpdate(statement);
0246: } finally {
0247: defensiveClose(statement);
0248: }
0249: } finally {
0250: connection.close();
0251: }
0252: }
0253:
0254: private boolean executeHasResultRows(DbPreparedStatement statement,
0255: DbPreparedStatementHandler handler) {
0256: executeQuery(statement, handler);
0257:
0258: return getResultSet(statement).hasResultRows();
0259:
0260: }
0261:
0262: /**
0263: * Safely and quickly verifies if a select query returns any rows. It
0264: * relies on the wrapped {@link DbResultSet#hasResultRows()} method, but
0265: * also automatically closes the statement after its execution.
0266: * <h3>Example</h3>
0267: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
0268: *Select select = new Select(datasource);
0269: *select.from("person");
0270: *boolean result = manager.executeHasResultRows(select);
0271: *</pre>
0272: *
0273: * @param query the query builder instance that needs to be executed
0274: * @return <code>true</code> when rows were returned by the query; or
0275: * <p><code>false</code> otherwise
0276: * @exception DatabaseException see {@link
0277: * DbPreparedStatement#executeQuery()}and {@link
0278: * DbResultSet#hasResultRows()}
0279: * @see DbPreparedStatement#executeQuery()
0280: * @see DbResultSet#hasResultRows()
0281: * @see DbPreparedStatementHandler
0282: * @since 1.0
0283: */
0284: public boolean executeHasResultRows(ReadQuery query)
0285: throws DatabaseException {
0286: return executeHasResultRows(query, null);
0287: }
0288:
0289: /**
0290: * Safely verifies if a customizable select query returns any rows. It
0291: * relies on the wrapped {@link DbResultSet#hasResultRows()} method, but
0292: * also automatically closes the statement after its execution and allows
0293: * customization of the prepared statement through an optional instance of
0294: * {@link DbPreparedStatementHandler}.
0295: * <h3>Example</h3>
0296: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
0297: *Select select = new Select(datasource);
0298: *select.from("person").whereParameter("name", "=");
0299: *final String name = "you";
0300: *boolean result = manager.executeHasResultRows(select, new DbPreparedStatementHandler() {
0301: * public void setParameters(DbPreparedStatement statement)
0302: * {
0303: * statement
0304: * .setString("name", name);
0305: * }
0306: * });</pre>
0307: *
0308: * @param query the query builder instance that needs to be executed
0309: * @param handler an instance of <code>DbPreparedStatementHandler</code>
0310: * that will be used to customize the query execution; or
0311: * <code>null</code> if you don't want to customize it at all
0312: * @return <code>true</code> when rows were returned by the query; or
0313: * <p><code>false</code> otherwise
0314: * @exception DatabaseException see {@link
0315: * DbPreparedStatement#executeQuery()}and {@link
0316: * DbResultSet#hasResultRows()}
0317: * @see DbPreparedStatement#executeQuery()
0318: * @see DbResultSet#hasResultRows()
0319: * @see DbPreparedStatementHandler
0320: * @since 1.0
0321: */
0322: public boolean executeHasResultRows(ReadQuery query,
0323: DbPreparedStatementHandler handler)
0324: throws DatabaseException {
0325: if (null == query)
0326: throw new IllegalArgumentException("query can't be null.");
0327:
0328: DbConnection connection = getConnection();
0329: try {
0330: DbPreparedStatement statement = getPreparedStatement(query,
0331: handler, connection);
0332: try {
0333: boolean result = executeHasResultRows(statement,
0334: handler);
0335:
0336: if (handler != null) {
0337: try {
0338: handler
0339: .concludeResults(getResultSet(statement));
0340: } catch (SQLException e) {
0341: statement.handleException();
0342: throw new DatabaseException(e);
0343: }
0344: }
0345:
0346: return result;
0347: } finally {
0348: defensiveClose(statement);
0349: }
0350: } finally {
0351: connection.close();
0352: }
0353: }
0354:
0355: /**
0356: * Safely and quickly retrieves the first cell as a <code>String</code>
0357: * from the results of a select query. It relies on the wrapped {@link
0358: * DbResultSet#getFirstString()} method, but also automatically closes the
0359: * statement after its execution.
0360: * <h3>Example</h3>
0361: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
0362: *Select select = new Select(datasource);
0363: *select.field("name").from("person");
0364: *String result = manager.executeGetFirstString(select);
0365: *</pre>
0366: *
0367: * @param query the query builder instance that needs to be executed
0368: * @return the first <code>String</code> in the query's resultset
0369: * @exception DatabaseException see {@link
0370: * DbPreparedStatement#executeQuery()}and {@link
0371: * DbResultSet#getFirstString()}
0372: * @see DbPreparedStatement#executeQuery()
0373: * @see DbResultSet#getFirstString()
0374: * @see DbPreparedStatementHandler
0375: * @since 1.0
0376: */
0377: public String executeGetFirstString(ReadQuery query)
0378: throws DatabaseException {
0379: return executeGetFirstString(query, null);
0380: }
0381:
0382: /**
0383: * Safely retrieves the first cell as a <code>String</code> from the
0384: * results of a customizable select query. It relies on the wrapped {@link
0385: * DbResultSet#getFirstString()} method, but also automatically closes the
0386: * statement after its execution and allows customization of the prepared
0387: * statement through an optional instance of {@link
0388: * DbPreparedStatementHandler}.
0389: * <h3>Example</h3>
0390: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
0391: *Select select = new Select(datasource);
0392: *select.field("first").from("person").whereParameter("last", "=");
0393: *final String last = "Smith";
0394: *String result = manager.executeGetFirstString(select, new DbPreparedStatementHandler() {
0395: * public void setParameters(DbPreparedStatement statement)
0396: * {
0397: * statement
0398: * .setString("last", last);
0399: * }
0400: * });</pre>
0401: *
0402: * @param query the query builder instance that needs to be executed
0403: * @param handler an instance of <code>DbPreparedStatementHandler</code>
0404: * that will be used to customize the query execution; or
0405: * <code>null</code> if you don't want to customize it at all
0406: * @return the first <code>String</code> in the query's resultset
0407: * @exception DatabaseException see {@link
0408: * DbPreparedStatement#executeQuery()}and {@link
0409: * DbResultSet#getFirstString()}
0410: * @see DbPreparedStatement#executeQuery()
0411: * @see DbResultSet#getFirstString()
0412: * @see DbPreparedStatementHandler
0413: * @since 1.0
0414: */
0415: public String executeGetFirstString(ReadQuery query,
0416: DbPreparedStatementHandler handler)
0417: throws DatabaseException {
0418: if (null == query)
0419: throw new IllegalArgumentException("query can't be null.");
0420:
0421: DbConnection connection = getConnection();
0422: try {
0423: DbPreparedStatement statement = getPreparedStatement(query,
0424: handler, connection);
0425: try {
0426: statement.setFetchSize(1);
0427:
0428: String result = null;
0429:
0430: if (executeHasResultRows(statement, handler)) {
0431: result = getResultSet(statement).getFirstString();
0432: }
0433:
0434: if (handler != null) {
0435: try {
0436: handler
0437: .concludeResults(getResultSet(statement));
0438: } catch (SQLException e) {
0439: statement.handleException();
0440: throw new DatabaseException(e);
0441: }
0442: }
0443:
0444: return result;
0445: } finally {
0446: defensiveClose(statement);
0447: }
0448: } finally {
0449: connection.close();
0450: }
0451: }
0452:
0453: /**
0454: * Safely and quickly retrieves the first cell as a <code>boolean</code>
0455: * from the results of a select query. It relies on the wrapped {@link
0456: * DbResultSet#getFirstBoolean()} method, but also automatically closes
0457: * the statement after its execution.
0458: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
0459: * for an example code snippet, it's 100% analogue.
0460: *
0461: * @param query the query builder instance that needs to be executed
0462: * @return the first <code>boolean</code> in the query's resultset
0463: * @exception DatabaseException see {@link
0464: * DbPreparedStatement#executeQuery()}and {@link
0465: * DbResultSet#getFirstBoolean()}
0466: * @see DbPreparedStatement#executeQuery()
0467: * @see DbResultSet#getFirstBoolean()
0468: * @see DbPreparedStatementHandler
0469: * @since 1.0
0470: */
0471: public boolean executeGetFirstBoolean(ReadQuery query)
0472: throws DatabaseException {
0473: return executeGetFirstBoolean(query, null);
0474: }
0475:
0476: /**
0477: * Safely retrieves the first cell as a <code>boolean</code> from the
0478: * results of a customizable select query. It relies on the wrapped {@link
0479: * DbResultSet#getFirstBoolean()} method, but also automatically closes
0480: * the statement after its execution and allows customization of the
0481: * prepared statement through an optional instance of {@link
0482: * DbPreparedStatementHandler}.
0483: * <p>Refer to {@link
0484: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
0485: * executeGetFirstString} for an example code snippet, it's 100% analogue.
0486: *
0487: * @param query the query builder instance that needs to be executed
0488: * @param handler an instance of <code>DbPreparedStatementHandler</code>
0489: * that will be used to customize the query execution; or
0490: * <code>null</code> if you don't want to customize it at all
0491: * @return the first <code>boolean</code> in the query's resultset
0492: * @exception DatabaseException see {@link
0493: * DbPreparedStatement#executeQuery()}and {@link
0494: * DbResultSet#getFirstBoolean()}
0495: * @see DbPreparedStatement#executeQuery()
0496: * @see DbResultSet#getFirstBoolean()
0497: * @see DbPreparedStatementHandler
0498: * @since 1.0
0499: */
0500: public boolean executeGetFirstBoolean(ReadQuery query,
0501: DbPreparedStatementHandler handler)
0502: throws DatabaseException {
0503: if (null == query)
0504: throw new IllegalArgumentException("query can't be null.");
0505:
0506: DbConnection connection = getConnection();
0507: try {
0508: DbPreparedStatement statement = getPreparedStatement(query,
0509: handler, connection);
0510: try {
0511: statement.setFetchSize(1);
0512:
0513: boolean result = false;
0514:
0515: if (executeHasResultRows(statement, handler)) {
0516: result = getResultSet(statement).getFirstBoolean();
0517: }
0518:
0519: if (handler != null) {
0520: try {
0521: handler
0522: .concludeResults(getResultSet(statement));
0523: } catch (SQLException e) {
0524: statement.handleException();
0525: throw new DatabaseException(e);
0526: }
0527: }
0528:
0529: return result;
0530: } finally {
0531: defensiveClose(statement);
0532: }
0533: } finally {
0534: connection.close();
0535: }
0536: }
0537:
0538: /**
0539: * Safely and quickly retrieves the first cell as a <code>byte</code> from
0540: * the results of a select query. It relies on the wrapped {@link
0541: * DbResultSet#getFirstByte()} method, but also automatically closes the
0542: * statement after its execution.
0543: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
0544: * for an example code snippet, it's 100% analogue.
0545: *
0546: * @param query the query builder instance that needs to be executed
0547: * @return the first <code>byte</code> in the query's resultset
0548: * @exception DatabaseException see {@link
0549: * DbPreparedStatement#executeQuery()}and {@link
0550: * DbResultSet#getFirstByte()}
0551: * @see DbPreparedStatement#executeQuery()
0552: * @see DbResultSet#getFirstByte()
0553: * @see DbPreparedStatementHandler
0554: * @since 1.0
0555: */
0556: public byte executeGetFirstByte(ReadQuery query)
0557: throws DatabaseException {
0558: return executeGetFirstByte(query, null);
0559: }
0560:
0561: /**
0562: * Safely retrieves the first cell as a <code>byte</code> from the results
0563: * of a customizable select query. It relies on the wrapped {@link
0564: * DbResultSet#getFirstByte()} method, but also automatically closes the
0565: * statement after its execution and allows customization of the prepared
0566: * statement through an optional instance of {@link
0567: * DbPreparedStatementHandler}.
0568: * <p>Refer to {@link
0569: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
0570: * executeGetFirstString} for an example code snippet, it's 100% analogue.
0571: *
0572: * @param query the query builder instance that needs to be executed
0573: * @param handler an instance of <code>DbPreparedStatementHandler</code>
0574: * that will be used to customize the query execution; or
0575: * <code>null</code> if you don't want to customize it at all
0576: * @return the first <code>byte</code> in the query's resultset
0577: * @exception DatabaseException see {@link
0578: * DbPreparedStatement#executeQuery()}and {@link
0579: * DbResultSet#getFirstByte()}
0580: * @see DbPreparedStatement#executeQuery()
0581: * @see DbResultSet#getFirstByte()
0582: * @see DbPreparedStatementHandler
0583: * @since 1.0
0584: */
0585: public byte executeGetFirstByte(ReadQuery query,
0586: DbPreparedStatementHandler handler)
0587: throws DatabaseException {
0588: if (null == query)
0589: throw new IllegalArgumentException("query can't be null.");
0590:
0591: DbConnection connection = getConnection();
0592: try {
0593: DbPreparedStatement statement = getPreparedStatement(query,
0594: handler, connection);
0595: try {
0596: statement.setFetchSize(1);
0597:
0598: byte result = -1;
0599:
0600: if (executeHasResultRows(statement, handler)) {
0601: result = getResultSet(statement).getFirstByte();
0602: }
0603:
0604: if (handler != null) {
0605: try {
0606: handler
0607: .concludeResults(getResultSet(statement));
0608: } catch (SQLException e) {
0609: statement.handleException();
0610: throw new DatabaseException(e);
0611: }
0612: }
0613:
0614: return result;
0615: } finally {
0616: defensiveClose(statement);
0617: }
0618: } finally {
0619: connection.close();
0620: }
0621: }
0622:
0623: /**
0624: * Safely and quickly retrieves the first cell as a <code>short</code>
0625: * from the results of a select query. It relies on the wrapped {@link
0626: * DbResultSet#getFirstShort()} method, but also automatically closes the
0627: * statement after its execution.
0628: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
0629: * for an example code snippet, it's 100% analogue.
0630: *
0631: * @param query the query builder instance that needs to be executed
0632: * @return the first <code>short</code> in the query's resultset
0633: * @exception DatabaseException see {@link
0634: * DbPreparedStatement#executeQuery()}and {@link
0635: * DbResultSet#getFirstShort()}
0636: * @see DbPreparedStatement#executeQuery()
0637: * @see DbResultSet#getFirstShort()
0638: * @see DbPreparedStatementHandler
0639: * @since 1.0
0640: */
0641: public short executeGetFirstShort(ReadQuery query)
0642: throws DatabaseException {
0643: return executeGetFirstShort(query, null);
0644: }
0645:
0646: /**
0647: * Safely retrieves the first cell as a <code>short</code> from the
0648: * results of a customizable select query. It relies on the wrapped {@link
0649: * DbResultSet#getFirstShort()} method, but also automatically closes the
0650: * statement after its execution and allows customization of the prepared
0651: * statement through an optional instance of {@link
0652: * DbPreparedStatementHandler}.
0653: * <p>Refer to {@link
0654: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
0655: * executeGetFirstString} for an example code snippet, it's 100% analogue.
0656: *
0657: * @param query the query builder instance that needs to be executed
0658: * @param handler an instance of <code>DbPreparedStatementHandler</code>
0659: * that will be used to customize the query execution; or
0660: * <code>null</code> if you don't want to customize it at all
0661: * @return the first <code>short</code> in the query's resultset
0662: * @exception DatabaseException see {@link
0663: * DbPreparedStatement#executeQuery()}and {@link
0664: * DbResultSet#getFirstShort()}
0665: * @see DbPreparedStatement#executeQuery()
0666: * @see DbResultSet#getFirstShort()
0667: * @see DbPreparedStatementHandler
0668: * @since 1.0
0669: */
0670: public short executeGetFirstShort(ReadQuery query,
0671: DbPreparedStatementHandler handler)
0672: throws DatabaseException {
0673: if (null == query)
0674: throw new IllegalArgumentException("query can't be null.");
0675:
0676: DbConnection connection = getConnection();
0677: try {
0678: DbPreparedStatement statement = getPreparedStatement(query,
0679: handler, connection);
0680: try {
0681: statement.setFetchSize(1);
0682:
0683: short result = -1;
0684:
0685: if (executeHasResultRows(statement, handler)) {
0686: result = getResultSet(statement).getFirstShort();
0687: }
0688:
0689: if (handler != null) {
0690: try {
0691: handler
0692: .concludeResults(getResultSet(statement));
0693: } catch (SQLException e) {
0694: statement.handleException();
0695: throw new DatabaseException(e);
0696: }
0697: }
0698:
0699: return result;
0700: } finally {
0701: defensiveClose(statement);
0702: }
0703: } finally {
0704: connection.close();
0705: }
0706: }
0707:
0708: /**
0709: * Safely and quickly retrieves the first cell as a <code>int</code> from
0710: * the results of a select query. It relies on the wrapped {@link
0711: * DbResultSet#getFirstInt()} method, but also automatically closes the
0712: * statement after its execution.
0713: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
0714: * for an example code snippet, it's 100% analogue.
0715: *
0716: * @param query the query builder instance that needs to be executed
0717: * @return the first <code>int</code> in the query's resultset
0718: * @exception DatabaseException see {@link
0719: * DbPreparedStatement#executeQuery()}and {@link DbResultSet#getFirstInt()}
0720: * @see DbPreparedStatement#executeQuery()
0721: * @see DbResultSet#getFirstInt()
0722: * @see DbPreparedStatementHandler
0723: * @since 1.0
0724: */
0725: public int executeGetFirstInt(ReadQuery query)
0726: throws DatabaseException {
0727: return executeGetFirstInt(query, null);
0728: }
0729:
0730: /**
0731: * Safely retrieves the first cell as a <code>int</code> from the results
0732: * of a customizable select query. It relies on the wrapped {@link
0733: * DbResultSet#getFirstInt()} method, but also automatically closes the
0734: * statement after its execution and allows customization of the prepared
0735: * statement through an optional instance of {@link
0736: * DbPreparedStatementHandler}.
0737: * <p>Refer to {@link
0738: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
0739: * executeGetFirstString} for an example code snippet, it's 100% analogue.
0740: *
0741: * @param query the query builder instance that needs to be executed
0742: * @param handler an instance of <code>DbPreparedStatementHandler</code>
0743: * that will be used to customize the query execution; or
0744: * <code>null</code> if you don't want to customize it at all
0745: * @return the first <code>int</code> in the query's resultset
0746: * @exception DatabaseException see {@link
0747: * DbPreparedStatement#executeQuery()}and {@link DbResultSet#getFirstInt()}
0748: * @see DbPreparedStatement#executeQuery()
0749: * @see DbResultSet#getFirstInt()
0750: * @see DbPreparedStatementHandler
0751: * @since 1.0
0752: */
0753: public int executeGetFirstInt(ReadQuery query,
0754: DbPreparedStatementHandler handler)
0755: throws DatabaseException {
0756: if (null == query)
0757: throw new IllegalArgumentException("query can't be null.");
0758:
0759: DbConnection connection = getConnection();
0760: try {
0761: DbPreparedStatement statement = getPreparedStatement(query,
0762: handler, connection);
0763: try {
0764: statement.setFetchSize(1);
0765:
0766: int result = -1;
0767:
0768: if (executeHasResultRows(statement, handler)) {
0769: result = getResultSet(statement).getFirstInt();
0770: }
0771:
0772: if (handler != null) {
0773: try {
0774: handler
0775: .concludeResults(getResultSet(statement));
0776: } catch (SQLException e) {
0777: statement.handleException();
0778: throw new DatabaseException(e);
0779: }
0780: }
0781:
0782: return result;
0783: } finally {
0784: defensiveClose(statement);
0785: }
0786: } finally {
0787: connection.close();
0788: }
0789: }
0790:
0791: /**
0792: * Safely and quickly retrieves the first cell as a <code>long</code> from
0793: * the results of a select query. It relies on the wrapped {@link
0794: * DbResultSet#getFirstLong()} method, but also automatically closes the
0795: * statement after its execution.
0796: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
0797: * for an example code snippet, it's 100% analogue.
0798: *
0799: * @param query the query builder instance that needs to be executed
0800: * @return the first <code>long</code> in the query's resultset
0801: * @exception DatabaseException see {@link
0802: * DbPreparedStatement#executeQuery()}and {@link
0803: * DbResultSet#getFirstLong()}
0804: * @see DbPreparedStatement#executeQuery()
0805: * @see DbResultSet#getFirstLong()
0806: * @see DbPreparedStatementHandler
0807: * @since 1.0
0808: */
0809: public long executeGetFirstLong(ReadQuery query)
0810: throws DatabaseException {
0811: return executeGetFirstLong(query, null);
0812: }
0813:
0814: /**
0815: * Safely retrieves the first cell as a <code>long</code> from the results
0816: * of a customizable select query. It relies on the wrapped {@link
0817: * DbResultSet#getFirstLong()} method, but also automatically closes the
0818: * statement after its execution and allows customization of the prepared
0819: * statement through an optional instance of {@link
0820: * DbPreparedStatementHandler}.
0821: * <p>Refer to {@link
0822: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
0823: * executeGetFirstString} for an example code snippet, it's 100% analogue.
0824: *
0825: * @param query the query builder instance that needs to be executed
0826: * @param handler an instance of <code>DbPreparedStatementHandler</code>
0827: * that will be used to customize the query execution; or
0828: * <code>null</code> if you don't want to customize it at all
0829: * @return the first <code>long</code> in the query's resultset
0830: * @exception DatabaseException see {@link
0831: * DbPreparedStatement#executeQuery()}and {@link
0832: * DbResultSet#getFirstLong()}
0833: * @see DbPreparedStatement#executeQuery()
0834: * @see DbResultSet#getFirstLong()
0835: * @see DbPreparedStatementHandler
0836: * @since 1.0
0837: */
0838: public long executeGetFirstLong(ReadQuery query,
0839: DbPreparedStatementHandler handler)
0840: throws DatabaseException {
0841: if (null == query)
0842: throw new IllegalArgumentException("query can't be null.");
0843:
0844: DbConnection connection = getConnection();
0845: try {
0846: DbPreparedStatement statement = getPreparedStatement(query,
0847: handler, connection);
0848: try {
0849: statement.setFetchSize(1);
0850:
0851: long result = -1;
0852:
0853: if (executeHasResultRows(statement, handler)) {
0854: result = getResultSet(statement).getFirstLong();
0855: }
0856:
0857: if (handler != null) {
0858: try {
0859: handler
0860: .concludeResults(getResultSet(statement));
0861: } catch (SQLException e) {
0862: statement.handleException();
0863: throw new DatabaseException(e);
0864: }
0865: }
0866:
0867: return result;
0868: } finally {
0869: defensiveClose(statement);
0870: }
0871: } finally {
0872: connection.close();
0873: }
0874: }
0875:
0876: /**
0877: * Safely and quickly retrieves the first cell as a <code>float</code>
0878: * from the results of a select query. It relies on the wrapped {@link
0879: * DbResultSet#getFirstFloat()} method, but also automatically closes the
0880: * statement after its execution.
0881: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
0882: * for an example code snippet, it's 100% analogue.
0883: *
0884: * @param query the query builder instance that needs to be executed
0885: * @return the first <code>float</code> in the query's resultset
0886: * @exception DatabaseException see {@link
0887: * DbPreparedStatement#executeQuery()}and {@link
0888: * DbResultSet#getFirstFloat()}
0889: * @see DbPreparedStatement#executeQuery()
0890: * @see DbResultSet#getFirstFloat()
0891: * @see DbPreparedStatementHandler
0892: * @since 1.0
0893: */
0894: public float executeGetFirstFloat(ReadQuery query)
0895: throws DatabaseException {
0896: return executeGetFirstFloat(query, null);
0897: }
0898:
0899: /**
0900: * Safely retrieves the first cell as a <code>float</code> from the
0901: * results of a customizable select query. It relies on the wrapped {@link
0902: * DbResultSet#getFirstFloat()} method, but also automatically closes the
0903: * statement after its execution and allows customization of the prepared
0904: * statement through an optional instance of {@link
0905: * DbPreparedStatementHandler}.
0906: * <p>Refer to {@link
0907: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
0908: * executeGetFirstString} for an example code snippet, it's 100% analogue.
0909: *
0910: * @param query the query builder instance that needs to be executed
0911: * @param handler an instance of <code>DbPreparedStatementHandler</code>
0912: * that will be used to customize the query execution; or
0913: * <code>null</code> if you don't want to customize it at all
0914: * @return the first <code>float</code> in the query's resultset
0915: * @exception DatabaseException see {@link
0916: * DbPreparedStatement#executeQuery()}and {@link
0917: * DbResultSet#getFirstFloat()}
0918: * @see DbPreparedStatement#executeQuery()
0919: * @see DbResultSet#getFirstFloat()
0920: * @see DbPreparedStatementHandler
0921: * @since 1.0
0922: */
0923: public float executeGetFirstFloat(ReadQuery query,
0924: DbPreparedStatementHandler handler)
0925: throws DatabaseException {
0926: if (null == query)
0927: throw new IllegalArgumentException("query can't be null.");
0928:
0929: DbConnection connection = getConnection();
0930: try {
0931: DbPreparedStatement statement = getPreparedStatement(query,
0932: handler, connection);
0933: try {
0934: statement.setFetchSize(1);
0935:
0936: float result = -1;
0937:
0938: if (executeHasResultRows(statement, handler)) {
0939: result = getResultSet(statement).getFirstFloat();
0940: }
0941:
0942: if (handler != null) {
0943: try {
0944: handler
0945: .concludeResults(getResultSet(statement));
0946: } catch (SQLException e) {
0947: statement.handleException();
0948: throw new DatabaseException(e);
0949: }
0950: }
0951:
0952: return result;
0953: } finally {
0954: defensiveClose(statement);
0955: }
0956: } finally {
0957: connection.close();
0958: }
0959: }
0960:
0961: /**
0962: * Safely and quickly retrieves the first cell as a <code>double</code>
0963: * from the results of a select query. It relies on the wrapped {@link
0964: * DbResultSet#getFirstDouble()} method, but also automatically closes the
0965: * statement after its execution.
0966: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
0967: * for an example code snippet, it's 100% analogue.
0968: *
0969: * @param query the query builder instance that needs to be executed
0970: * @return the first <code>double</code> in the query's resultset
0971: * @exception DatabaseException see {@link
0972: * DbPreparedStatement#executeQuery()}and {@link
0973: * DbResultSet#getFirstDouble()}
0974: * @see DbPreparedStatement#executeQuery()
0975: * @see DbResultSet#getFirstDouble()
0976: * @see DbPreparedStatementHandler
0977: * @since 1.0
0978: */
0979: public double executeGetFirstDouble(ReadQuery query)
0980: throws DatabaseException {
0981: return executeGetFirstDouble(query, null);
0982: }
0983:
0984: /**
0985: * Safely retrieves the first cell as a <code>double</code> from the
0986: * results of a customizable select query. It relies on the wrapped {@link
0987: * DbResultSet#getFirstDouble()} method, but also automatically closes the
0988: * statement after its execution and allows customization of the prepared
0989: * statement through an optional instance of {@link
0990: * DbPreparedStatementHandler}.
0991: * <p>Refer to {@link
0992: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
0993: * executeGetFirstString} for an example code snippet, it's 100% analogue.
0994: *
0995: * @param query the query builder instance that needs to be executed
0996: * @param handler an instance of <code>DbPreparedStatementHandler</code>
0997: * that will be used to customize the query execution; or
0998: * <code>null</code> if you don't want to customize it at all
0999: * @return the first <code>double</code> in the query's resultset
1000: * @exception DatabaseException see {@link
1001: * DbPreparedStatement#executeQuery()}and {@link
1002: * DbResultSet#getFirstDouble()}
1003: * @see DbPreparedStatement#executeQuery()
1004: * @see DbResultSet#getFirstDouble()
1005: * @see DbPreparedStatementHandler
1006: * @since 1.0
1007: */
1008: public double executeGetFirstDouble(ReadQuery query,
1009: DbPreparedStatementHandler handler)
1010: throws DatabaseException {
1011: if (null == query)
1012: throw new IllegalArgumentException("query can't be null.");
1013:
1014: DbConnection connection = getConnection();
1015: try {
1016: DbPreparedStatement statement = getPreparedStatement(query,
1017: handler, connection);
1018: try {
1019: statement.setFetchSize(1);
1020:
1021: double result = -1;
1022:
1023: if (executeHasResultRows(statement, handler)) {
1024: result = getResultSet(statement).getFirstDouble();
1025: }
1026:
1027: if (handler != null) {
1028: try {
1029: handler
1030: .concludeResults(getResultSet(statement));
1031: } catch (SQLException e) {
1032: statement.handleException();
1033: throw new DatabaseException(e);
1034: }
1035: }
1036:
1037: return result;
1038: } finally {
1039: defensiveClose(statement);
1040: }
1041: } finally {
1042: connection.close();
1043: }
1044: }
1045:
1046: /**
1047: * Safely and quickly retrieves the first cell as a <code>byte</code>
1048: * array from the results of a select query. It relies on the wrapped
1049: * {@link DbResultSet#getFirstBytes()} method, but also automatically
1050: * closes the statement after its execution.
1051: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
1052: * for an example code snippet, it's 100% analogue.
1053: *
1054: * @param query the query builder instance that needs to be executed
1055: * @return the first <code>byte</code> array in the query's resultset
1056: * @exception DatabaseException see {@link
1057: * DbPreparedStatement#executeQuery()}and {@link
1058: * DbResultSet#getFirstBytes()}
1059: * @see DbPreparedStatement#executeQuery()
1060: * @see DbResultSet#getFirstBytes()
1061: * @see DbPreparedStatementHandler
1062: * @since 1.0
1063: */
1064: public byte[] executeGetFirstBytes(ReadQuery query)
1065: throws DatabaseException {
1066: return executeGetFirstBytes(query, null);
1067: }
1068:
1069: /**
1070: * Safely retrieves the first cell as a <code>byte</code> array from the
1071: * results of a customizable select query. It relies on the wrapped {@link
1072: * DbResultSet#getFirstBytes()} method, but also automatically closes the
1073: * statement after its execution and allows customization of the prepared
1074: * statement through an optional instance of {@link
1075: * DbPreparedStatementHandler}.
1076: * <p>Refer to {@link
1077: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
1078: * executeGetFirstString} for an example code snippet, it's 100% analogue.
1079: *
1080: * @param query the query builder instance that needs to be executed
1081: * @param handler an instance of <code>DbPreparedStatementHandler</code>
1082: * that will be used to customize the query execution; or
1083: * <code>null</code> if you don't want to customize it at all
1084: * @return the first <code>byte</code> array in the query's resultset
1085: * @exception DatabaseException see {@link
1086: * DbPreparedStatement#executeQuery()}and {@link
1087: * DbResultSet#getFirstBytes()}
1088: * @see DbPreparedStatement#executeQuery()
1089: * @see DbResultSet#getFirstBytes()
1090: * @see DbPreparedStatementHandler
1091: * @since 1.0
1092: */
1093: public byte[] executeGetFirstBytes(ReadQuery query,
1094: DbPreparedStatementHandler handler)
1095: throws DatabaseException {
1096: if (null == query)
1097: throw new IllegalArgumentException("query can't be null.");
1098:
1099: DbConnection connection = getConnection();
1100: try {
1101: DbPreparedStatement statement = getPreparedStatement(query,
1102: handler, connection);
1103: try {
1104: statement.setFetchSize(1);
1105:
1106: byte[] result = null;
1107:
1108: if (executeHasResultRows(statement, handler)) {
1109: result = getResultSet(statement).getFirstBytes();
1110: }
1111:
1112: if (handler != null) {
1113: try {
1114: handler
1115: .concludeResults(getResultSet(statement));
1116: } catch (SQLException e) {
1117: statement.handleException();
1118: throw new DatabaseException(e);
1119: }
1120: }
1121:
1122: return result;
1123: } finally {
1124: defensiveClose(statement);
1125: }
1126: } finally {
1127: connection.close();
1128: }
1129: }
1130:
1131: /**
1132: * Safely and quickly retrieves the first cell as a sql <code>Date</code>
1133: * from the results of a select query. It relies on the wrapped {@link
1134: * DbResultSet#getFirstDate()} method, but also automatically closes the
1135: * statement after its execution.
1136: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
1137: * for an example code snippet, it's 100% analogue.
1138: *
1139: * @param query the query builder instance that needs to be executed
1140: * @return the first sql <code>Date</code> in the query's resultset
1141: * @exception DatabaseException see {@link
1142: * DbPreparedStatement#executeQuery()}and {@link
1143: * DbResultSet#getFirstDate()}
1144: * @see DbPreparedStatement#executeQuery()
1145: * @see DbResultSet#getFirstDate()
1146: * @see DbPreparedStatementHandler
1147: * @since 1.0
1148: */
1149: public java.sql.Date executeGetFirstDate(ReadQuery query)
1150: throws DatabaseException {
1151: return executeGetFirstDate(query,
1152: (DbPreparedStatementHandler) null);
1153: }
1154:
1155: /**
1156: * Safely retrieves the first cell as a sql <code>Date</code> from the
1157: * results of a customizable select query. It relies on the wrapped {@link
1158: * DbResultSet#getFirstDate()} method, but also automatically closes the
1159: * statement after its execution and allows customization of the prepared
1160: * statement through an optional instance of {@link
1161: * DbPreparedStatementHandler}.
1162: * <p>Refer to {@link
1163: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
1164: * executeGetFirstString} for an example code snippet, it's 100% analogue.
1165: *
1166: * @param query the query builder instance that needs to be executed
1167: * @param handler an instance of <code>DbPreparedStatementHandler</code>
1168: * that will be used to customize the query execution; or
1169: * <code>null</code> if you don't want to customize it at all
1170: * @return the first sql <code>Date</code> in the query's resultset
1171: * @exception DatabaseException see {@link
1172: * DbPreparedStatement#executeQuery()}and {@link
1173: * DbResultSet#getFirstDate()}
1174: * @see DbPreparedStatement#executeQuery()
1175: * @see DbResultSet#getFirstDate()
1176: * @see DbPreparedStatementHandler
1177: * @since 1.0
1178: */
1179: public java.sql.Date executeGetFirstDate(ReadQuery query,
1180: DbPreparedStatementHandler handler)
1181: throws DatabaseException {
1182: if (null == query)
1183: throw new IllegalArgumentException("query can't be null.");
1184:
1185: DbConnection connection = getConnection();
1186: try {
1187: DbPreparedStatement statement = getPreparedStatement(query,
1188: handler, connection);
1189: try {
1190: statement.setFetchSize(1);
1191:
1192: java.sql.Date result = null;
1193:
1194: if (executeHasResultRows(statement, handler)) {
1195: result = getResultSet(statement).getFirstDate();
1196: }
1197:
1198: if (handler != null) {
1199: try {
1200: handler
1201: .concludeResults(getResultSet(statement));
1202: } catch (SQLException e) {
1203: statement.handleException();
1204: throw new DatabaseException(e);
1205: }
1206: }
1207:
1208: return result;
1209: } finally {
1210: defensiveClose(statement);
1211: }
1212: } finally {
1213: connection.close();
1214: }
1215: }
1216:
1217: /**
1218: * Safely and quickly retrieves the first cell as a sql <code>Date</code>
1219: * from the results of a select query. It relies on the wrapped {@link
1220: * DbResultSet#getFirstDate(Calendar)} method, but also automatically
1221: * closes the statement after its execution.
1222: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
1223: * for an example code snippet, it's 100% analogue.
1224: *
1225: * @param query the query builder instance that needs to be executed
1226: * @param cal the <code>Calendar</code> object to use in constructing the
1227: * date
1228: * @return the first sql <code>Date</code> in the query's resultset
1229: * @exception DatabaseException see {@link
1230: * DbPreparedStatement#executeQuery()}and {@link
1231: * DbResultSet#getFirstDate(Calendar)}
1232: * @see DbPreparedStatement#executeQuery()
1233: * @see DbResultSet#getFirstDate(Calendar)
1234: * @see DbPreparedStatementHandler
1235: * @since 1.0
1236: */
1237: public java.sql.Date executeGetFirstDate(ReadQuery query,
1238: Calendar cal) throws DatabaseException {
1239: return executeGetFirstDate(query, cal, null);
1240: }
1241:
1242: /**
1243: * Safely retrieves the first cell as a sql <code>Date</code> from the
1244: * results of a customizable select query. It relies on the wrapped {@link
1245: * DbResultSet#getFirstDate(Calendar)} method, but also automatically
1246: * closes the statement after its execution and allows customization of
1247: * the prepared statement through an optional instance of {@link
1248: * DbPreparedStatementHandler}.
1249: * <p>Refer to {@link
1250: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
1251: * executeGetFirstString} for an example code snippet, it's 100% analogue.
1252: *
1253: * @param query the query builder instance that needs to be executed
1254: * @param cal the <code>Calendar</code> object to use in constructing the
1255: * date
1256: * @param handler an instance of <code>DbPreparedStatementHandler</code>
1257: * that will be used to customize the query execution; or
1258: * <code>null</code> if you don't want to customize it at all
1259: * @return the first sql <code>Date</code> in the query's resultset
1260: * @exception DatabaseException see {@link
1261: * DbPreparedStatement#executeQuery()}and {@link
1262: * DbResultSet#getFirstDate(Calendar)}
1263: * @see DbPreparedStatement#executeQuery()
1264: * @see DbResultSet#getFirstDate(Calendar)
1265: * @see DbPreparedStatementHandler
1266: * @since 1.0
1267: */
1268: public java.sql.Date executeGetFirstDate(ReadQuery query,
1269: Calendar cal, DbPreparedStatementHandler handler)
1270: throws DatabaseException {
1271: if (null == query)
1272: throw new IllegalArgumentException("query can't be null.");
1273:
1274: DbConnection connection = getConnection();
1275: try {
1276: DbPreparedStatement statement = getPreparedStatement(query,
1277: handler, connection);
1278: try {
1279: statement.setFetchSize(1);
1280:
1281: java.sql.Date result = null;
1282:
1283: if (executeHasResultRows(statement, handler)) {
1284: result = getResultSet(statement).getFirstDate(cal);
1285: }
1286:
1287: if (handler != null) {
1288: try {
1289: handler
1290: .concludeResults(getResultSet(statement));
1291: } catch (SQLException e) {
1292: statement.handleException();
1293: throw new DatabaseException(e);
1294: }
1295: }
1296:
1297: return result;
1298: } finally {
1299: defensiveClose(statement);
1300: }
1301: } finally {
1302: connection.close();
1303: }
1304: }
1305:
1306: /**
1307: * Safely and quickly retrieves the first cell as a sql <code>Time</code>
1308: * from the results of a select query. It relies on the wrapped {@link
1309: * DbResultSet#getFirstTime()} method, but also automatically closes the
1310: * statement after its execution.
1311: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
1312: * for an example code snippet, it's 100% analogue.
1313: *
1314: * @param query the query builder instance that needs to be executed
1315: * @return the first sql <code>Time</code> in the query's resultset
1316: * @exception DatabaseException see {@link
1317: * DbPreparedStatement#executeQuery()}and {@link
1318: * DbResultSet#getFirstTime()}
1319: * @see DbPreparedStatement#executeQuery()
1320: * @see DbResultSet#getFirstTime()
1321: * @see DbPreparedStatementHandler
1322: * @since 1.0
1323: */
1324: public java.sql.Time executeGetFirstTime(ReadQuery query)
1325: throws DatabaseException {
1326: return executeGetFirstTime(query,
1327: (DbPreparedStatementHandler) null);
1328: }
1329:
1330: /**
1331: * Safely retrieves the first cell as a sql <code>Time</code> from the
1332: * results of a customizable select query. It relies on the wrapped {@link
1333: * DbResultSet#getFirstTime()} method, but also automatically closes the
1334: * statement after its execution and allows customization of the prepared
1335: * statement through an optional instance of {@link
1336: * DbPreparedStatementHandler}.
1337: * <p>Refer to {@link
1338: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
1339: * executeGetFirstString} for an example code snippet, it's 100% analogue.
1340: *
1341: * @param query the query builder instance that needs to be executed
1342: * @param handler an instance of <code>DbPreparedStatementHandler</code>
1343: * that will be used to customize the query execution; or
1344: * <code>null</code> if you don't want to customize it at all
1345: * @return the first sql <code>Time</code> in the query's resultset
1346: * @exception DatabaseException see {@link
1347: * DbPreparedStatement#executeQuery()}and {@link
1348: * DbResultSet#getFirstTime()}
1349: * @see DbPreparedStatement#executeQuery()
1350: * @see DbResultSet#getFirstTime()
1351: * @see DbPreparedStatementHandler
1352: * @since 1.0
1353: */
1354: public java.sql.Time executeGetFirstTime(ReadQuery query,
1355: DbPreparedStatementHandler handler)
1356: throws DatabaseException {
1357: if (null == query)
1358: throw new IllegalArgumentException("query can't be null.");
1359:
1360: DbConnection connection = getConnection();
1361: try {
1362: DbPreparedStatement statement = getPreparedStatement(query,
1363: handler, connection);
1364: try {
1365: statement.setFetchSize(1);
1366:
1367: java.sql.Time result = null;
1368:
1369: if (executeHasResultRows(statement, handler)) {
1370: result = getResultSet(statement).getFirstTime();
1371: }
1372:
1373: if (handler != null) {
1374: try {
1375: handler
1376: .concludeResults(getResultSet(statement));
1377: } catch (SQLException e) {
1378: statement.handleException();
1379: throw new DatabaseException(e);
1380: }
1381: }
1382:
1383: return result;
1384: } finally {
1385: defensiveClose(statement);
1386: }
1387: } finally {
1388: connection.close();
1389: }
1390: }
1391:
1392: /**
1393: * Safely and quickly retrieves the first cell as a sql <code>Time</code>
1394: * from the results of a select query. It relies on the wrapped {@link
1395: * DbResultSet#getFirstTime(Calendar)} method, but also automatically
1396: * closes the statement after its execution.
1397: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
1398: * for an example code snippet, it's 100% analogue.
1399: *
1400: * @param query the query builder instance that needs to be executed
1401: * @param cal the <code>Calendar</code> object to use in constructing the
1402: * time
1403: * @return the first sql <code>Time</code> in the query's resultset
1404: * @exception DatabaseException see {@link
1405: * DbPreparedStatement#executeQuery()}and {@link
1406: * DbResultSet#getFirstTime(Calendar)}
1407: * @see DbPreparedStatement#executeQuery()
1408: * @see DbResultSet#getFirstTime(Calendar)
1409: * @see DbPreparedStatementHandler
1410: * @since 1.0
1411: */
1412: public java.sql.Time executeGetFirstTime(ReadQuery query,
1413: Calendar cal) throws DatabaseException {
1414: return executeGetFirstTime(query, cal, null);
1415: }
1416:
1417: /**
1418: * Safely retrieves the first cell as a sql <code>Time</code> from the
1419: * results of a customizable select query. It relies on the wrapped {@link
1420: * DbResultSet#getFirstTime(Calendar)} method, but also automatically
1421: * closes the statement after its execution and allows customization of
1422: * the prepared statement through an optional instance of {@link
1423: * DbPreparedStatementHandler}.
1424: * <p>Refer to {@link
1425: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
1426: * executeGetFirstString} for an example code snippet, it's 100% analogue.
1427: *
1428: * @param query the query builder instance that needs to be executed
1429: * @param cal the <code>Calendar</code> object to use in constructing the
1430: * time
1431: * @param handler an instance of <code>DbPreparedStatementHandler</code>
1432: * that will be used to customize the query execution; or
1433: * <code>null</code> if you don't want to customize it at all
1434: * @return the first sql <code>Time</code> in the query's resultset
1435: * @exception DatabaseException see {@link
1436: * DbPreparedStatement#executeQuery()}and {@link
1437: * DbResultSet#getFirstTime(Calendar)}
1438: * @see DbPreparedStatement#executeQuery()
1439: * @see DbResultSet#getFirstTime(Calendar)
1440: * @see DbPreparedStatementHandler
1441: * @since 1.0
1442: */
1443: public java.sql.Time executeGetFirstTime(ReadQuery query,
1444: Calendar cal, DbPreparedStatementHandler handler)
1445: throws DatabaseException {
1446: if (null == query)
1447: throw new IllegalArgumentException("query can't be null.");
1448:
1449: DbConnection connection = getConnection();
1450: try {
1451: DbPreparedStatement statement = getPreparedStatement(query,
1452: handler, connection);
1453: try {
1454: statement.setFetchSize(1);
1455:
1456: java.sql.Time result = null;
1457:
1458: if (executeHasResultRows(statement, handler)) {
1459: result = getResultSet(statement).getFirstTime(cal);
1460: }
1461:
1462: if (handler != null) {
1463: try {
1464: handler
1465: .concludeResults(getResultSet(statement));
1466: } catch (SQLException e) {
1467: statement.handleException();
1468: throw new DatabaseException(e);
1469: }
1470: }
1471:
1472: return result;
1473: } finally {
1474: defensiveClose(statement);
1475: }
1476: } finally {
1477: connection.close();
1478: }
1479: }
1480:
1481: /**
1482: * Safely and quickly retrieves the first cell as a sql
1483: * <code>Timestamp</code> from the results of a select query. It relies on
1484: * the wrapped {@link DbResultSet#getFirstTimestamp()} method, but also
1485: * automatically closes the statement after its execution.
1486: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
1487: * for an example code snippet, it's 100% analogue.
1488: *
1489: * @param query the query builder instance that needs to be executed
1490: * @return the first sql <code>Timestamp</code> in the query's resultset
1491: * @exception DatabaseException see {@link
1492: * DbPreparedStatement#executeQuery()}and {@link
1493: * DbResultSet#getFirstTimestamp()}
1494: * @see DbPreparedStatement#executeQuery()
1495: * @see DbResultSet#getFirstTimestamp()
1496: * @see DbPreparedStatementHandler
1497: * @since 1.0
1498: */
1499: public java.sql.Timestamp executeGetFirstTimestamp(ReadQuery query)
1500: throws DatabaseException {
1501: return executeGetFirstTimestamp(query,
1502: (DbPreparedStatementHandler) null);
1503: }
1504:
1505: /**
1506: * Safely retrieves the first cell as a sql <code>Timestamp</code> from
1507: * the results of a customizable select query. It relies on the wrapped
1508: * {@link DbResultSet#getFirstTimestamp()} method, but also automatically
1509: * closes the statement after its execution and allows customization of
1510: * the prepared statement through an optional instance of {@link
1511: * DbPreparedStatementHandler}.
1512: * <p>Refer to {@link
1513: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
1514: * executeGetFirstString} for an example code snippet, it's 100% analogue.
1515: *
1516: * @param query the query builder instance that needs to be executed
1517: * @param handler an instance of <code>DbPreparedStatementHandler</code>
1518: * that will be used to customize the query execution; or
1519: * <code>null</code> if you don't want to customize it at all
1520: * @return the first sql <code>Timestamp</code> in the query's resultset
1521: * @exception DatabaseException see {@link
1522: * DbPreparedStatement#executeQuery()}and {@link
1523: * DbResultSet#getFirstTimestamp()}
1524: * @see DbPreparedStatement#executeQuery()
1525: * @see DbResultSet#getFirstTimestamp()
1526: * @see DbPreparedStatementHandler
1527: * @since 1.0
1528: */
1529: public java.sql.Timestamp executeGetFirstTimestamp(ReadQuery query,
1530: DbPreparedStatementHandler handler)
1531: throws DatabaseException {
1532: if (null == query)
1533: throw new IllegalArgumentException("query can't be null.");
1534:
1535: DbConnection connection = getConnection();
1536: try {
1537: DbPreparedStatement statement = getPreparedStatement(query,
1538: handler, connection);
1539: try {
1540: statement.setFetchSize(1);
1541:
1542: java.sql.Timestamp result = null;
1543:
1544: if (executeHasResultRows(statement, handler)) {
1545: result = getResultSet(statement)
1546: .getFirstTimestamp();
1547: }
1548:
1549: if (handler != null) {
1550: try {
1551: handler
1552: .concludeResults(getResultSet(statement));
1553: } catch (SQLException e) {
1554: statement.handleException();
1555: throw new DatabaseException(e);
1556: }
1557: }
1558:
1559: return result;
1560: } finally {
1561: defensiveClose(statement);
1562: }
1563: } finally {
1564: connection.close();
1565: }
1566: }
1567:
1568: /**
1569: * Safely and quickly retrieves the first cell as a sql
1570: * <code>Timestamp</code> from the results of a select query. It relies on
1571: * the wrapped {@link DbResultSet#getFirstTimestamp(Calendar)} method, but
1572: * also automatically closes the statement after its execution.
1573: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
1574: * for an example code snippet, it's 100% analogue.
1575: *
1576: * @param query the query builder instance that needs to be executed
1577: * @param cal the <code>Calendar</code> object to use in constructing the
1578: * timestamp
1579: * @return the first sql <code>Timestamp</code> in the query's resultset
1580: * @exception DatabaseException see {@link
1581: * DbPreparedStatement#executeQuery()}and {@link
1582: * DbResultSet#getFirstTimestamp(Calendar)}
1583: * @see DbPreparedStatement#executeQuery()
1584: * @see DbResultSet#getFirstTimestamp(Calendar)
1585: * @see DbPreparedStatementHandler
1586: * @since 1.0
1587: */
1588: public java.sql.Timestamp executeGetFirstTimestamp(ReadQuery query,
1589: Calendar cal) throws DatabaseException {
1590: return executeGetFirstTimestamp(query, cal, null);
1591: }
1592:
1593: /**
1594: * Safely retrieves the first cell as a sql <code>Timestamp</code> from
1595: * the results of a customizable select query. It relies on the wrapped
1596: * {@link DbResultSet#getFirstTimestamp(Calendar)} method, but also
1597: * automatically closes the statement after its execution and allows
1598: * customization of the prepared statement through an optional instance of
1599: * {@link DbPreparedStatementHandler}.
1600: * <p>Refer to {@link
1601: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
1602: * executeGetFirstString} for an example code snippet, it's 100% analogue.
1603: *
1604: * @param query the query builder instance that needs to be executed
1605: * @param cal the <code>Calendar</code> object to use in constructing the
1606: * timestamp
1607: * @param handler an instance of <code>DbPreparedStatementHandler</code>
1608: * that will be used to customize the query execution; or
1609: * <code>null</code> if you don't want to customize it at all
1610: * @return the first sql <code>Timestamp</code> in the query's resultset
1611: * @exception DatabaseException see {@link
1612: * DbPreparedStatement#executeQuery()}and {@link
1613: * DbResultSet#getFirstTimestamp(Calendar)}
1614: * @see DbPreparedStatement#executeQuery()
1615: * @see DbResultSet#getFirstTimestamp(Calendar)
1616: * @see DbPreparedStatementHandler
1617: * @since 1.0
1618: */
1619: public java.sql.Timestamp executeGetFirstTimestamp(ReadQuery query,
1620: Calendar cal, DbPreparedStatementHandler handler)
1621: throws DatabaseException {
1622: if (null == query)
1623: throw new IllegalArgumentException("query can't be null.");
1624:
1625: DbConnection connection = getConnection();
1626: try {
1627: DbPreparedStatement statement = getPreparedStatement(query,
1628: handler, connection);
1629: try {
1630: statement.setFetchSize(1);
1631:
1632: java.sql.Timestamp result = null;
1633:
1634: if (executeHasResultRows(statement, handler)) {
1635: result = getResultSet(statement).getFirstTimestamp(
1636: cal);
1637: }
1638:
1639: if (handler != null) {
1640: try {
1641: handler
1642: .concludeResults(getResultSet(statement));
1643: } catch (SQLException e) {
1644: statement.handleException();
1645: throw new DatabaseException(e);
1646: }
1647: }
1648:
1649: return result;
1650: } finally {
1651: defensiveClose(statement);
1652: }
1653: } finally {
1654: connection.close();
1655: }
1656: }
1657:
1658: /**
1659: * Safely and quickly retrieves the first cell as an ASCII
1660: * <code>InputStream</code> from the results of a select query. It relies
1661: * on the wrapped {@link DbResultSet#getFirstAsciiStream()} method, but
1662: * also automatically closes the statement after its execution.
1663: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
1664: * for an example code snippet, it's 100% analogue.
1665: *
1666: * @param query the query builder instance that needs to be executed
1667: * @param user an instance of <code>InputStreamUser</code>
1668: * that contains the logic that will be executed with this stream
1669: * @return the return value from the <code>useInputStream</code> method of
1670: * the provided <code>InputStreamUser</code> instance
1671: * @exception DatabaseException see {@link
1672: * DbPreparedStatement#executeQuery()}and {@link
1673: * DbResultSet#getFirstAsciiStream()}
1674: * @exception InnerClassException when errors occurs inside the
1675: * <code>InputStreamUser</code>
1676: * @see InputStreamUser
1677: * @see DbPreparedStatement#executeQuery()
1678: * @see DbResultSet#getFirstAsciiStream()
1679: * @see DbPreparedStatementHandler
1680: * @since 1.0
1681: */
1682: public <ResultType> ResultType executeUseFirstAsciiStream(
1683: ReadQuery query, InputStreamUser user)
1684: throws DatabaseException, InnerClassException {
1685: return (ResultType) executeUseFirstAsciiStream(query, user,
1686: null);
1687: }
1688:
1689: /**
1690: * Safely retrieves the first cell as an ASCII <code>InputStream</code>
1691: * from the results of a customizable select query. It relies on the
1692: * wrapped {@link DbResultSet#getFirstAsciiStream()} method, but also
1693: * automatically closes the statement after its execution and allows
1694: * customization of the prepared statement through an optional instance of
1695: * {@link DbPreparedStatementHandler}.
1696: * <p>Refer to {@link
1697: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
1698: * executeGetFirstString} for an example code snippet, it's 100% analogue.
1699: *
1700: * @param query the query builder instance that needs to be executed
1701: * @param user an instance of <code>InputStreamUser</code>
1702: * that contains the logic that will be executed with this stream
1703: * @param handler an instance of <code>DbPreparedStatementHandler</code>
1704: * that will be used to customize the query execution; or
1705: * <code>null</code> if you don't want to customize it at all
1706: * @return the return value from the <code>useInputStream</code> method of
1707: * the provided <code>InputStreamUser</code> instance
1708: * @exception DatabaseException see {@link
1709: * DbPreparedStatement#executeQuery()}and {@link
1710: * DbResultSet#getFirstAsciiStream()}
1711: * @exception InnerClassException when errors occurs inside the
1712: * <code>InputStreamUser</code>
1713: * @see InputStreamUser
1714: * @see DbPreparedStatement#executeQuery()
1715: * @see DbResultSet#getFirstAsciiStream()
1716: * @see DbPreparedStatementHandler
1717: * @since 1.0
1718: */
1719: public <ResultType> ResultType executeUseFirstAsciiStream(
1720: ReadQuery query, InputStreamUser user,
1721: DbPreparedStatementHandler handler)
1722: throws DatabaseException, InnerClassException {
1723: if (null == query)
1724: throw new IllegalArgumentException("query can't be null.");
1725: if (null == user)
1726: throw new IllegalArgumentException("user can't be null.");
1727:
1728: DbConnection connection = getConnection();
1729: try {
1730: DbPreparedStatement statement = getPreparedStatement(query,
1731: handler, connection);
1732: InputStream stream = null;
1733: try {
1734: statement.setFetchSize(1);
1735:
1736: if (executeHasResultRows(statement, handler)) {
1737: stream = getResultSet(statement)
1738: .getFirstAsciiStream();
1739: }
1740:
1741: if (handler != null) {
1742: try {
1743: handler
1744: .concludeResults(getResultSet(statement));
1745: } catch (SQLException e) {
1746: statement.handleException();
1747: throw new DatabaseException(e);
1748: }
1749: }
1750:
1751: return (ResultType) user.useInputStream(stream);
1752: } finally {
1753: defensiveClose(stream);
1754: defensiveClose(statement);
1755: }
1756: } finally {
1757: connection.close();
1758: }
1759: }
1760:
1761: /**
1762: * Safely and quickly retrieves the first cell as an character
1763: * <code>Reader</code> from the results of a select query. It relies on
1764: * the wrapped {@link DbResultSet#getFirstCharacterStream()} method, but
1765: * also automatically closes the statement after its execution.
1766: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
1767: * for an example code snippet, it's 100% analogue.
1768: *
1769: * @param query the query builder instance that needs to be executed
1770: * @param user an instance of <code>ReaderUser</code>
1771: * that contains the logic that will be executed with this reader
1772: * @return the return value from the <code>useReader</code> method of
1773: * the provided <code>ReaderUser</code> instance
1774: * @exception DatabaseException see {@link
1775: * DbPreparedStatement#executeQuery()}and {@link
1776: * DbResultSet#getFirstCharacterStream()}
1777: * @exception InnerClassException when errors occurs inside the
1778: * <code>ReaderUser</code>
1779: * @see ReaderUser
1780: * @see DbPreparedStatement#executeQuery()
1781: * @see DbResultSet#getFirstCharacterStream()
1782: * @see DbPreparedStatementHandler
1783: * @since 1.0
1784: */
1785: public <ResultType> ResultType executeUseFirstCharacterStream(
1786: ReadQuery query, ReaderUser user) throws DatabaseException,
1787: InnerClassException {
1788: return (ResultType) executeUseFirstCharacterStream(query, user,
1789: null);
1790: }
1791:
1792: /**
1793: * Safely retrieves the first cell as an character <code>Reader</code>
1794: * from the results of a customizable select query. It relies on the
1795: * wrapped {@link DbResultSet#getFirstCharacterStream()} method, but also
1796: * automatically closes the statement after its execution and allows
1797: * customization of the prepared statement through an optional instance of
1798: * {@link DbPreparedStatementHandler}.
1799: * <p>Refer to {@link
1800: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
1801: * executeGetFirstString} for an example code snippet, it's 100% analogue.
1802: *
1803: * @param query the query builder instance that needs to be executed
1804: * @param user an instance of <code>ReaderUser</code>
1805: * that contains the logic that will be executed with this reader
1806: * @param handler an instance of <code>DbPreparedStatementHandler</code>
1807: * that will be used to customize the query execution; or
1808: * <code>null</code> if you don't want to customize it at all
1809: * @return the return value from the <code>useReader</code> method of
1810: * the provided <code>ReaderUser</code> instance
1811: * @exception DatabaseException see {@link
1812: * DbPreparedStatement#executeQuery()}and {@link
1813: * DbResultSet#getFirstCharacterStream()}
1814: * @exception InnerClassException when errors occurs inside the
1815: * <code>ReaderUser</code>
1816: * @see ReaderUser
1817: * @see DbPreparedStatement#executeQuery()
1818: * @see DbResultSet#getFirstCharacterStream()
1819: * @see DbPreparedStatementHandler
1820: * @since 1.0
1821: */
1822: public <ResultType> ResultType executeUseFirstCharacterStream(
1823: ReadQuery query, ReaderUser user,
1824: DbPreparedStatementHandler handler)
1825: throws DatabaseException, InnerClassException {
1826: if (null == query)
1827: throw new IllegalArgumentException("query can't be null.");
1828: if (null == user)
1829: throw new IllegalArgumentException("user can't be null.");
1830:
1831: DbConnection connection = getConnection();
1832: try {
1833: DbPreparedStatement statement = getPreparedStatement(query,
1834: handler, connection);
1835: Reader reader = null;
1836: try {
1837: statement.setFetchSize(1);
1838:
1839: if (executeHasResultRows(statement, handler)) {
1840: reader = getResultSet(statement)
1841: .getFirstCharacterStream();
1842: }
1843:
1844: if (handler != null) {
1845: try {
1846: handler
1847: .concludeResults(getResultSet(statement));
1848: } catch (SQLException e) {
1849: statement.handleException();
1850: throw new DatabaseException(e);
1851: }
1852: }
1853:
1854: return (ResultType) user.useReader(reader);
1855: } finally {
1856: defensiveClose(reader);
1857: defensiveClose(statement);
1858: }
1859: } finally {
1860: connection.close();
1861: }
1862: }
1863:
1864: /**
1865: * Safely and quickly retrieves the first cell as an binary
1866: * <code>InputStream</code> from the results of a select query. It relies
1867: * on the wrapped {@link DbResultSet#getFirstBinaryStream()} method, but
1868: * also automatically closes the statement after its execution.
1869: * <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
1870: * for an example code snippet, it's 100% analogue.
1871: *
1872: * @param query the query builder instance that needs to be executed
1873: * @param user an instance of <code>InputStreamUser</code>
1874: * that contains the logic that will be executed with this stream
1875: * @return the return value from the <code>useInputStream</code> method of
1876: * the provided <code>InputStreamUser</code> instance
1877: * @exception DatabaseException see {@link
1878: * DbPreparedStatement#executeQuery()}and {@link
1879: * DbResultSet#getFirstBinaryStream()}
1880: * @exception InnerClassException when errors occurs inside the
1881: * <code>InputStreamUser</code>
1882: * @see InputStreamUser
1883: * @see DbPreparedStatement#executeQuery()
1884: * @see DbResultSet#getFirstBinaryStream()
1885: * @see DbPreparedStatementHandler
1886: * @since 1.0
1887: */
1888: public <ResultType> ResultType executeUseFirstBinaryStream(
1889: ReadQuery query, InputStreamUser user)
1890: throws DatabaseException, InnerClassException {
1891: return (ResultType) executeUseFirstBinaryStream(query, user,
1892: null);
1893: }
1894:
1895: /**
1896: * Safely retrieves the first cell as an binary <code>InputStream</code>
1897: * from the results of a customizable select query. It relies on the
1898: * wrapped {@link DbResultSet#getFirstBinaryStream()} method, but also
1899: * automatically closes the statement after its execution and allows
1900: * customization of the prepared statement through an optional instance of
1901: * {@link DbPreparedStatementHandler}.
1902: * <p>Refer to {@link
1903: * #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
1904: * executeGetFirstString} for an example code snippet, it's 100% analogue.
1905: *
1906: * @param query the query builder instance that needs to be executed
1907: * @param user an instance of <code>InputStreamUser</code>
1908: * that contains the logic that will be executed with this stream
1909: * @param handler an instance of <code>DbPreparedStatementHandler</code>
1910: * that will be used to customize the query execution; or
1911: * <code>null</code> if you don't want to customize it at all
1912: * @return the return value from the <code>useInputStream</code> method of
1913: * the provided <code>InputStreamUser</code> instance
1914: * @exception DatabaseException see {@link
1915: * DbPreparedStatement#executeQuery()}and {@link
1916: * DbResultSet#getFirstBinaryStream()}
1917: * @exception InnerClassException when errors occurs inside the
1918: * <code>InputStreamUser</code>
1919: * @see InputStreamUser
1920: * @see DbPreparedStatement#executeQuery()
1921: * @see DbResultSet#getFirstBinaryStream()
1922: * @see DbPreparedStatementHandler
1923: * @since 1.0
1924: */
1925: public <ResultType> ResultType executeUseFirstBinaryStream(
1926: ReadQuery query, InputStreamUser user,
1927: DbPreparedStatementHandler handler)
1928: throws DatabaseException, InnerClassException {
1929: if (null == query)
1930: throw new IllegalArgumentException("query can't be null.");
1931: if (null == user)
1932: throw new IllegalArgumentException("user can't be null.");
1933:
1934: DbConnection connection = getConnection();
1935: try {
1936: DbPreparedStatement statement = getPreparedStatement(query,
1937: handler, connection);
1938: InputStream stream = null;
1939: try {
1940: statement.setFetchSize(1);
1941:
1942: if (executeHasResultRows(statement, handler)) {
1943: stream = getResultSet(statement)
1944: .getFirstBinaryStream();
1945: }
1946:
1947: if (handler != null) {
1948: try {
1949: handler
1950: .concludeResults(getResultSet(statement));
1951: } catch (SQLException e) {
1952: statement.handleException();
1953: throw new DatabaseException(e);
1954: }
1955: }
1956:
1957: return (ResultType) user.useInputStream(stream);
1958: } finally {
1959: defensiveClose(stream);
1960: defensiveClose(statement);
1961: }
1962: } finally {
1963: connection.close();
1964: }
1965: }
1966:
1967: /**
1968: * Safely and quickly fetches the first row from the results of a select
1969: * query. It relies on the wrapped {@link
1970: * #fetch(ResultSet, DbRowProcessor)} method, but automatically closes the
1971: * statement after its execution.
1972: * <h3>Example</h3>
1973: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
1974: *Select select = new Select(datasource);
1975: *select.from("person").where("name", "=", "me");
1976: *DbRowProcessor processor = new YourProcessor();
1977: *boolean result = manager.executeFetchFirst(select, processor);</pre>
1978: *
1979: * @param query the query builder instance that needs to be executed
1980: * @param rowProcessor a <code>DbRowProcessor</code> instance, if it's
1981: * <code>null</code> no processing will be performed on the fetched row
1982: * @return <code>true</code> if a row was retrieved; or
1983: * <p><code>false</code> if there are no more rows .
1984: * @exception DatabaseException see {@link
1985: * DbPreparedStatement#executeQuery()}and {@link
1986: * #fetch(ResultSet, DbRowProcessor)}
1987: * @see #fetch(ResultSet, DbRowProcessor)
1988: * @see DbRowProcessor
1989: * @since 1.0
1990: */
1991: public boolean executeFetchFirst(ReadQuery query,
1992: DbRowProcessor rowProcessor) throws DatabaseException {
1993: return executeFetchFirst(query, rowProcessor, null);
1994: }
1995:
1996: /**
1997: * Safely fetches the first row from the results of a customizable select
1998: * query. It relies on the wrapped {@link
1999: * #fetch(ResultSet, DbRowProcessor)} method, but also automatically
2000: * closes the statement after its execution and allows customization of
2001: * the prepared statement through an optional instance of {@link
2002: * DbPreparedStatementHandler}.
2003: * <h3>Example</h3>
2004: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
2005: *Select select = new Select(datasource);
2006: *select.from("person").whereParameter("name", "=");
2007: *DbRowProcessor processor = new YourProcessor();
2008: *final String name = "you";
2009: *boolean result = manager.executeFetchFirst(select, processor, new DbPreparedStatementHandler() {
2010: * public void setParameters(DbPreparedStatement statement)
2011: * {
2012: * statement
2013: * .setString("name", name);
2014: * }
2015: * });</pre>
2016: *
2017: * @param query the query builder instance that needs to be executed
2018: * @param rowProcessor a <code>DbRowProcessor</code> instance, if it's
2019: * <code>null</code> no processing will be performed on the fetched row
2020: * @param handler an instance of <code>DbPreparedStatementHandler</code>
2021: * that will be used to customize the query execution; or
2022: * <code>null</code> if you don't want to customize it at all
2023: * @return <code>true</code> if a row was retrieved; or
2024: * <p><code>false</code> if there are no more rows .
2025: * @exception DatabaseException see {@link
2026: * DbPreparedStatement#executeQuery()}and {@link
2027: * #fetch(ResultSet, DbRowProcessor)}
2028: * @see #fetch(ResultSet, DbRowProcessor)
2029: * @see DbRowProcessor
2030: * @since 1.0
2031: */
2032: public boolean executeFetchFirst(ReadQuery query,
2033: DbRowProcessor rowProcessor,
2034: DbPreparedStatementHandler handler)
2035: throws DatabaseException {
2036: if (null == query)
2037: throw new IllegalArgumentException("query can't be null.");
2038:
2039: DbConnection connection = getConnection();
2040: try {
2041: DbPreparedStatement statement = getPreparedStatement(query,
2042: handler, connection);
2043: try {
2044: statement.setFetchSize(1);
2045:
2046: executeQuery(statement, handler);
2047:
2048: boolean result = fetch(getResultSet(statement),
2049: rowProcessor);
2050:
2051: if (handler != null) {
2052: try {
2053: handler
2054: .concludeResults(getResultSet(statement));
2055: } catch (SQLException e) {
2056: statement.handleException();
2057: throw new DatabaseException(e);
2058: }
2059: }
2060:
2061: return result;
2062: } finally {
2063: defensiveClose(statement);
2064: }
2065: } finally {
2066: connection.close();
2067: }
2068: }
2069:
2070: /**
2071: * Safely and quickly fetches the first bean instance from the results of
2072: * a select query. It relies on the wrapped {@link
2073: * #executeFetchFirst(ReadQuery, DbRowProcessor)} method, but automatically
2074: * uses an appropriate {@link DbBeanFetcher} instance and returns the
2075: * resulting bean.
2076: * <h3>Example</h3>
2077: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
2078: *Select select = new Select(datasource);
2079: *select.from("person").fields(Person.class);
2080: *Person person = manager.executeFetchFirstBean(select, Person.class);</pre>
2081: *
2082: * @param query the query builder instance that needs to be executed
2083: * @param beanClass the class of the bean
2084: * @return <code>true</code> if a row was retrieved; or
2085: * <p><code>false</code> if there are no more rows .
2086: * @exception DatabaseException see {@link DbBeanFetcher} and {@link
2087: * #executeFetchFirst(ReadQuery, DbRowProcessor)}
2088: * @see #executeFetchFirst(ReadQuery, DbRowProcessor)
2089: * @see DbBeanFetcher
2090: * @since 1.0
2091: */
2092: public <BeanType> BeanType executeFetchFirstBean(ReadQuery query,
2093: Class<BeanType> beanClass) throws DatabaseException {
2094: return executeFetchFirstBean(query, beanClass, null);
2095: }
2096:
2097: /**
2098: * Safely fetches the first bean instance from the results of a
2099: * customizable select query. It relies on the wrapped {@link
2100: * #executeFetchFirst(ReadQuery, DbRowProcessor)} method, but automatically
2101: * uses an appropriate {@link DbBeanFetcher} instance, returns the
2102: * resulting bean and allows customization of the prepared statement
2103: * through an optional instance of {@link DbPreparedStatementHandler}.
2104: * <h3>Example</h3>
2105: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
2106: *Select select = new Select(datasource);
2107: *select.from("person").fields(Person.class).whereParameter("name", "=");
2108: *final String name = "you";
2109: *Person person = manager.executeFetchFirstBean(select, Person.class, new DbPreparedStatementHandler() {
2110: * public void setParameters(DbPreparedStatement statement)
2111: * {
2112: * statement
2113: * .setString("name", name);
2114: * }
2115: * });</pre>
2116: *
2117: * @param query the query builder instance that needs to be executed
2118: * @param beanClass the class of the bean
2119: * @param handler an instance of <code>DbPreparedStatementHandler</code>
2120: * that will be used to customize the query execution; or
2121: * <code>null</code> if you don't want to customize it at all
2122: * @return <code>true</code> if a row was retrieved; or
2123: * <p><code>false</code> if there are no more rows .
2124: * @exception DatabaseException see {@link DbBeanFetcher} and {@link
2125: * #executeFetchFirst(ReadQuery, DbRowProcessor)}
2126: * @see #executeFetchFirst(ReadQuery, DbRowProcessor)
2127: * @see DbBeanFetcher
2128: * @since 1.0
2129: */
2130: public <BeanType> BeanType executeFetchFirstBean(ReadQuery query,
2131: Class<BeanType> beanClass,
2132: DbPreparedStatementHandler handler)
2133: throws DatabaseException {
2134: if (null == query)
2135: throw new IllegalArgumentException("query can't be null.");
2136:
2137: DbBeanFetcher<BeanType> bean_fetcher = new DbBeanFetcher<BeanType>(
2138: getDatasource(), beanClass);
2139: if (executeFetchFirst(query, bean_fetcher, handler)) {
2140: return bean_fetcher.getBeanInstance();
2141: }
2142:
2143: return null;
2144: }
2145:
2146: /**
2147: * Safely and quickly fetches all the rows from the results of a select
2148: * query. It relies on the wrapped {@link
2149: * #fetchAll(ResultSet, DbRowProcessor)} method, but automatically closes
2150: * the statement after its execution.
2151: * <h3>Example</h3>
2152: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
2153: *Select select = new Select(datasource);
2154: *select.from("person").where("gender", "=", "m");
2155: *DbRowProcessor processor = new YourProcessor();
2156: *boolean result = manager.executeFetchAll(select, processor);</pre>
2157: *
2158: * @param query the query builder instance that needs to be executed
2159: * @param rowProcessor a <code>DbRowProcessor</code> instance, if it's
2160: * <code>null</code> no processing will be performed on the fetched rows
2161: * @return <code>true</code> if rows were retrieved; or
2162: * <p><code>false</code> if there are no more rows .
2163: * @exception DatabaseException see {@link
2164: * DbPreparedStatement#executeQuery()}and {@link
2165: * #fetchAll(ResultSet, DbRowProcessor)}
2166: * @see #fetchAll(ResultSet, DbRowProcessor)
2167: * @see DbRowProcessor
2168: * @since 1.0
2169: */
2170: public boolean executeFetchAll(ReadQuery query,
2171: DbRowProcessor rowProcessor) throws DatabaseException {
2172: return executeFetchAll(query, rowProcessor, null);
2173: }
2174:
2175: /**
2176: * Safely fetches all the rows from the results of a customizable select
2177: * query. It relies on the wrapped {@link
2178: * #fetchAll(ResultSet, DbRowProcessor)} method, but also automatically
2179: * closes the statement after its execution and allows customization of
2180: * the prepared statement through an optional instance of {@link
2181: * DbPreparedStatementHandler}.
2182: * <h3>Example</h3>
2183: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
2184: *Select select = new Select(datasource);
2185: *select.from("person").whereParameter("gender", "=");
2186: *DbRowProcessor processor = new YourProcessor();
2187: *final String name = "m";
2188: *boolean result = manager.executeFetchAll(select, processor, new DbPreparedStatementHandler() {
2189: * public void setParameters(DbPreparedStatement statement)
2190: * {
2191: * statement
2192: * .setString("gender", name);
2193: * }
2194: * });</pre>
2195: *
2196: * @param query the query builder instance that needs to be executed
2197: * @param rowProcessor a <code>DbRowProcessor</code> instance, if it's
2198: * <code>null</code> no processing will be performed on the fetched row
2199: * @param handler an instance of <code>DbPreparedStatementHandler</code>
2200: * that will be used to customize the query execution; or
2201: * <code>null</code> if you don't want to customize it at all
2202: * @return <code>true</code> if rows were retrieved; or
2203: * <p><code>false</code> if there are no more rows .
2204: * @exception DatabaseException see {@link
2205: * DbPreparedStatement#executeQuery()}and {@link
2206: * #fetchAll(ResultSet, DbRowProcessor)}
2207: * @see #fetchAll(ResultSet, DbRowProcessor)
2208: * @see DbRowProcessor
2209: * @since 1.0
2210: */
2211: public boolean executeFetchAll(ReadQuery query,
2212: DbRowProcessor rowProcessor,
2213: DbPreparedStatementHandler handler)
2214: throws DatabaseException {
2215: if (null == query)
2216: throw new IllegalArgumentException("query can't be null.");
2217:
2218: DbConnection connection = getConnection();
2219: try {
2220: DbPreparedStatement statement = getPreparedStatement(query,
2221: handler, connection);
2222: try {
2223: executeQuery(statement, handler);
2224:
2225: boolean result = fetchAll(getResultSet(statement),
2226: rowProcessor);
2227:
2228: if (handler != null) {
2229: try {
2230: handler
2231: .concludeResults(getResultSet(statement));
2232: } catch (SQLException e) {
2233: statement.handleException();
2234: throw new DatabaseException(e);
2235: }
2236: }
2237:
2238: return result;
2239: } finally {
2240: defensiveClose(statement);
2241: }
2242: } finally {
2243: connection.close();
2244: }
2245: }
2246:
2247: /**
2248: * Safely and quickly fetches the all the bean instances from the results
2249: * of a select query. It relies on the wrapped {@link
2250: * #executeFetchAll(ReadQuery, DbRowProcessor)} method, but automatically
2251: * uses an appropriate {@link DbBeanFetcher} instance and returns the
2252: * results.
2253: * <h3>Example</h3>
2254: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
2255: *Select select = new Select(datasource);
2256: *select.from("person").fields(Person.class).where("gender", "=", "m");
2257: *List persons = manager.executeFetchAllBeans(select, Person.class);</pre>
2258: *
2259: * @param query the query builder instance that needs to be executed
2260: * @param beanClass the class of the bean
2261: * @return <code>a List instance with all the beans, the list is empty if
2262: * no beans could be returned</code>
2263: * @exception DatabaseException see {@link DbBeanFetcher} and {@link
2264: * #executeFetchAll(ReadQuery, DbRowProcessor)}
2265: * @see #executeFetchAll(ReadQuery, DbRowProcessor)
2266: * @see DbBeanFetcher
2267: * @since 1.0
2268: */
2269: public <BeanType> List<BeanType> executeFetchAllBeans(
2270: ReadQuery query, Class<BeanType> beanClass)
2271: throws DatabaseException {
2272: return executeFetchAllBeans(query, beanClass, null);
2273: }
2274:
2275: /**
2276: * Safely fetches the all the bean instances from the results of a
2277: * customizable select query. It relies on the wrapped {@link
2278: * #executeFetchAll(ReadQuery, DbRowProcessor)} method, but automatically
2279: * uses an appropriate {@link DbBeanFetcher} instance, returns the results
2280: * and allows customization of the prepared statement through an optional
2281: * instance of {@link DbPreparedStatementHandler}.
2282: * <h3>Example</h3>
2283: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
2284: *Select select = new Select(datasource);
2285: *select.from("person").fields(Person.class).whereParameter("gender", "=");
2286: *final String name = "m";
2287: *List persons = manager.executeFetchAllBeans(select, Person.class, new DbPreparedStatementHandler() {
2288: * public void setParameters(DbPreparedStatement statement)
2289: * {
2290: * statement
2291: * .setString("gender", name);
2292: * }
2293: * });</pre>
2294: *
2295: * @param query the query builder instance that needs to be executed
2296: * @param beanClass the class of the bean
2297: * @param handler an instance of <code>DbPreparedStatementHandler</code>
2298: * that will be used to customize the query execution; or
2299: * <code>null</code> if you don't want to customize it at all
2300: * @return <code>a List instance with all the beans, the list is empty if
2301: * no beans could be returned</code>
2302: * @exception DatabaseException see {@link DbBeanFetcher} and {@link
2303: * #executeFetchAll(ReadQuery, DbRowProcessor)}
2304: * @see #executeFetchAll(ReadQuery, DbRowProcessor)
2305: * @see DbBeanFetcher
2306: * @since 1.0
2307: */
2308: public <BeanType> List<BeanType> executeFetchAllBeans(
2309: ReadQuery query, Class<BeanType> beanClass,
2310: DbPreparedStatementHandler handler)
2311: throws DatabaseException {
2312: if (null == query)
2313: throw new IllegalArgumentException("query can't be null.");
2314:
2315: DbBeanFetcher<BeanType> bean_fetcher = new DbBeanFetcher<BeanType>(
2316: getDatasource(), beanClass, true);
2317: executeFetchAll(query, bean_fetcher, handler);
2318:
2319: return bean_fetcher.getCollectedInstances();
2320: }
2321:
2322: /**
2323: * Executes a customizable select statement. It relies on the wrapped
2324: * {@link DbPreparedStatement#executeQuery()} method, but also
2325: * automatically closes the statement after its execution and allows
2326: * complete customization of the prepared statement through an optional
2327: * instance of {@link DbPreparedStatementHandler}.
2328: * <p>This method is typically used when you need to fully customize a
2329: * query at runtime, but still want to benefit of a safety net that
2330: * ensures that the allocated statement will be closed. Often another more
2331: * specialized method in this class will already serve your needs, so be
2332: * sure to verify that you actually need to intervene on every front.
2333: * <h3>Example</h3>
2334: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
2335: *Select select = new Select(datasource);
2336: *select
2337: * .field("first")
2338: * .field("last")
2339: * .from("person")
2340: * .whereParameter("name", "=");
2341: *final String name = "you";
2342: *String result = (String)manager.executeQuery(select, new DbPreparedStatementHandler() {
2343: * public void setParameters(DbPreparedStatement statement)
2344: * {
2345: * statement
2346: * .setString("name", name);
2347: * }
2348: *
2349: * public Object concludeResults(DbResultSet resultset)
2350: * throws SQLException
2351: * {
2352: * return resultset.getString("first")+" "+resultset.getString("last");
2353: * }
2354: * });</pre>
2355: *
2356: * @param query the query builder instance that needs to be executed
2357: * @param handler an instance of <code>DbPreparedStatementHandler</code>
2358: * that will be used to customize the query execution; or
2359: * <code>null</code> if you don't want to customize it at all
2360: * @return the object that was returned by the overridden {@link
2361: * DbResultSetHandler#concludeResults(DbResultSet) concludeResults}
2362: * method; or
2363: * <p><code>null</code> if this method wasn't overridden
2364: * @exception DatabaseException see {@link
2365: * DbPreparedStatement#executeQuery()}
2366: * @see DbPreparedStatement#executeQuery()
2367: * @see DbPreparedStatementHandler
2368: * @since 1.0
2369: */
2370: public <ResultType> ResultType executeQuery(ReadQuery query,
2371: DbPreparedStatementHandler handler)
2372: throws DatabaseException {
2373: if (null == query)
2374: throw new IllegalArgumentException("query can't be null.");
2375:
2376: DbConnection connection = getConnection();
2377: try {
2378: DbPreparedStatement statement = getPreparedStatement(query,
2379: handler, connection);
2380: try {
2381: executeQuery(statement, handler);
2382: if (null == handler) {
2383: return null;
2384: }
2385:
2386: try {
2387: return (ResultType) handler
2388: .concludeResults(getResultSet(statement));
2389: } catch (SQLException e) {
2390: statement.handleException();
2391: throw new DatabaseException(e);
2392: }
2393: } finally {
2394: defensiveClose(statement);
2395: }
2396: } finally {
2397: connection.close();
2398: }
2399: }
2400:
2401: /**
2402: * Executes a select statement and handle the results in a custom fashion.
2403: * It relies on the wrapped {@link DbPreparedStatement#executeQuery()}
2404: * method, but also automatically closes the statement after its execution
2405: * and allows interaction with the resultset through an optional instance
2406: * of {@link DbResultSetHandler}.
2407: * <p>This method is typically used when you need to interact with the
2408: * results of a query, but still want to benefit of a safety net that
2409: * ensures that the allocated statement will be closed. Often another more
2410: * specialized method in this class will already serve your needs, so be
2411: * sure to verify that there isn't another one that's better suited.
2412: * <h3>Example</h3>
2413: * <pre>DbQueryManager manager = new DbQueryManager(datasource);
2414: *Select select = new Select(datasource);
2415: *select
2416: * .field("first")
2417: * .field("last")
2418: * .from("person");
2419: *String result = (String)manager.executeQuery(select, new DbResultSetHandler() {
2420: * public Object concludeResults(DbResultSet resultset)
2421: * throws SQLException
2422: * {
2423: * return resultset.getString("first")+" "+resultset.getString("last");
2424: * }
2425: * });</pre>
2426: *
2427: * @param query the query builder instance that needs to be executed
2428: * @param handler an instance of <code><code>DbResultSetHandler</code></code>
2429: * that will be used to handle the results of the query execution; or
2430: * <code>null</code> if you don't want to customize it at all
2431: * @return the object that was returned by the overridden {@link
2432: * DbResultSetHandler#concludeResults(DbResultSet) concludeResults}
2433: * method; or
2434: * <p><code>null</code> if this method wasn't overridden
2435: * @exception DatabaseException see {@link
2436: * DbPreparedStatement#executeQuery()}
2437: * @see DbPreparedStatement#executeQuery()
2438: * @see DbResultSetHandler
2439: * @since 1.0
2440: */
2441: public <ResultType> ResultType executeQuery(ReadQuery query,
2442: DbResultSetHandler handler) throws DatabaseException {
2443: if (null == query)
2444: throw new IllegalArgumentException("query can't be null.");
2445:
2446: DbConnection connection = getConnection();
2447: try {
2448: DbPreparedStatement statement = getPreparedStatement(query,
2449: handler, connection);
2450: try {
2451: executeQuery(statement, null);
2452:
2453: if (handler != null) {
2454: try {
2455: return (ResultType) handler
2456: .concludeResults(getResultSet(statement));
2457: } catch (SQLException e) {
2458: statement.handleException();
2459: throw new DatabaseException(e);
2460: }
2461: }
2462:
2463: return null;
2464: } finally {
2465: defensiveClose(statement);
2466: }
2467: } finally {
2468: connection.close();
2469: }
2470: }
2471:
2472: /**
2473: * Reserves a database connection for a this particular thread for all the
2474: * instructions that are executed in the provided {@link DbConnectionUser}
2475: * instance.
2476: * <p>This is typically used to ensure that a series of operations is done
2477: * with the same connection, even though a database pool is used in the
2478: * background.
2479: * <h3>Example</h3>
2480: * <pre>Person person;
2481: *final Insert store_data = new Insert(datasource).into("person").fields(person);
2482: *final Select get_last_id = new Select(datasource).from("person").field("LAST_INSERT_ID()");
2483: *final DbQueryManager manager = new DbQueryManager(datasource);
2484: *int id = ((Integer)manager.reserveConnection(new DbConnectionUser() {
2485: * public Integer useConnection(DbConnection connection)
2486: * {
2487: * manager.executeUpdate(store_data);
2488: * return new Integer(manager.executeGetFirstInt(get_last_id));
2489: * }
2490: * })).intValue();</pre>
2491: *
2492: * @param user an instance of <code>DbConnectionUser</code> that contains
2493: * the logic that will be executed
2494: * @return the return value from the <code>useConnection</code> method of
2495: * the provided <code>DbConnectionUser</code> instance
2496: * @exception DatabaseException when errors occurs during the reservation
2497: * of a connection for this thread
2498: * @exception InnerClassException when errors occurs inside the
2499: * <code>DbConnectionUser</code>
2500: * @see DbConnectionUser#useConnection(DbConnection)
2501: * @since 1.0
2502: */
2503: public <ResultType> ResultType reserveConnection(
2504: DbConnectionUser user) throws InnerClassException,
2505: DatabaseException {
2506: if (null == user)
2507: throw new IllegalArgumentException("user can't be null.");
2508:
2509: DbConnection connection = mDatasource.getConnection();
2510: ConnectionPool pool = mDatasource.getPool();
2511: synchronized (pool) {
2512: boolean does_threadconnection_exist = pool
2513: .hasThreadConnection(Thread.currentThread());
2514: try {
2515: if (!does_threadconnection_exist)
2516: pool.registerThreadConnection(Thread
2517: .currentThread(), connection);
2518:
2519: return (ResultType) user.useConnection(connection);
2520: } finally {
2521: if (!does_threadconnection_exist)
2522: pool.unregisterThreadConnection(Thread
2523: .currentThread());
2524: }
2525: }
2526: }
2527:
2528: /**
2529: * Ensures that all the instructions that are executed in the provided
2530: * {@link DbTransactionUser} instance are executed inside a transaction
2531: * and committed afterwards. This doesn't mean that a new transaction will
2532: * always be created. If a transaction is already active, it will simply
2533: * be re-used. The commit will also only be take place if a new
2534: * transaction has actually been started, otherwise it's the
2535: * responsibility of the enclosing code to execute the commit. If an
2536: * runtime exception occurs during the execution and a new transaction has
2537: * been started beforehand, it will be automatically rolled back.
2538: * <p>If you need to explicitly roll back an active transaction, use the
2539: * {@link DbTransactionUser#rollback() rollback} method of the
2540: * <code>DbTransactionUser</code> class. If you use a regular rollback
2541: * method, it's possible that you're inside a nested transaction executed
2542: * and that after the rollback, other logic continues to be executed
2543: * outside the transaction. Using the correct {@link
2544: * DbTransactionUser#rollback() rollback} method, stops the execution of
2545: * the active <code>DbTransactionUser</code> and breaks out of any number
2546: * of them nesting.
2547: * <p>It's recommended to always use transactions through this method
2548: * since it ensures that transactional code can be re-used and enclosed in
2549: * other transactional code. Correctly using the regular
2550: * transaction-related methods requires great care and planning and often
2551: * results in error-prone and not reusable code.
2552: * <h3>Example</h3>
2553: * <pre>final Insert insert = new Insert(mDatasource).into("valuelist").field("value", 232);
2554: *final DbQueryManager manager = new DbQueryManager(datasource);
2555: *manager.inTransaction(new DbTransactionUserWithoutResult() {
2556: * public void useTransactionWithoutResult()
2557: * throws InnerClassException
2558: * {
2559: * manager.executeUpdate(insert);
2560: * manager.executeUpdate(insert);
2561: * }
2562: * });
2563: *</pre>
2564: *
2565: * @param user an instance of <code>DbTransactionUser</code> that contains
2566: * the logic that will be executed
2567: * @return the return value from the <code>useTransaction</code> method of
2568: * the provided <code>DbTransactionUser</code> instance
2569: * @exception DatabaseException when errors occurs during the handling of
2570: * the transaction
2571: * @exception InnerClassException when errors occurs inside the
2572: * <code>DbTransactionUser</code>
2573: * @see DbTransactionUser#useTransaction()
2574: * @see DbTransactionUserWithoutResult#useTransactionWithoutResult()
2575: * @since 1.0
2576: */
2577: public <ResultType> ResultType inTransaction(DbTransactionUser user)
2578: throws InnerClassException, DatabaseException {
2579: boolean started_transaction = false;
2580: DbConnection connection = null;
2581: try {
2582: synchronized (mDatasource) {
2583: connection = mDatasource.getConnection();
2584: int isolation = user.getTransactionIsolation();
2585: if (isolation != -1) {
2586: connection.setTransactionIsolation(isolation);
2587: }
2588: started_transaction = connection.beginTransaction();
2589: }
2590:
2591: ResultType result = (ResultType) user.useTransaction();
2592: if (started_transaction) {
2593: connection.commit();
2594: if (!mDatasource.isPooled()) {
2595: connection.close();
2596: }
2597: }
2598: return result;
2599: } catch (RollbackException e) {
2600: if (connection != null) {
2601: connection.rollback();
2602: if (!mDatasource.isPooled()) {
2603: connection.close();
2604: }
2605: }
2606:
2607: if (started_transaction) {
2608: return (ResultType) null;
2609: } else {
2610: throw e;
2611: }
2612: } catch (RuntimeException e) {
2613: if (started_transaction && connection != null) {
2614: try {
2615: if (e instanceof ControlFlowRuntimeException) {
2616: connection.commit();
2617: } else {
2618: connection.rollback();
2619: if (!mDatasource.isPooled()) {
2620: connection.close();
2621: }
2622: }
2623: } catch (DatabaseException e2) {
2624: // nothing that can be done about this
2625: // the connection is probably closed since
2626: // a database error occurred
2627: }
2628: }
2629: throw e;
2630: } catch (Error e) {
2631: if (started_transaction && connection != null) {
2632: try {
2633: connection.rollback();
2634: if (!mDatasource.isPooled()) {
2635: connection.close();
2636: }
2637: } catch (DatabaseException e2) {
2638: // nothing that can be done about this
2639: // the connection is probably closed since
2640: // a database error occurred
2641: }
2642: }
2643: throw e;
2644: }
2645: }
2646:
2647: /**
2648: * Executes a query statement in a connection of this
2649: * <code>DbQueryManager</code>'s <code>Datasource</code>. Functions
2650: * exactly as the wrapped {@link DbStatement#executeQuery(ReadQuery)} method.
2651: * <p>Note that the statement will not be automatically closed since using
2652: * this method implies that you still have to work with the resultset.
2653: *
2654: * @param query the query builder instance that should be executed
2655: * @return the statement that has been executed
2656: * @exception DatabaseException see {@link DbStatement#executeQuery(ReadQuery)}
2657: * @see DbStatement#executeQuery(ReadQuery)
2658: * @since 1.0
2659: */
2660: public DbStatement executeQuery(ReadQuery query)
2661: throws DatabaseException {
2662: if (null == query)
2663: throw new IllegalArgumentException("query can't be null.");
2664:
2665: DbStatement statement = getConnection().createStatement();
2666: statement.executeQuery(query);
2667: return statement;
2668: }
2669:
2670: /**
2671: * Fetches the next row of a resultset without processing it in any way.
2672: *
2673: * @param resultSet a valid <code>ResultSet</code> instance
2674: * @return <code>true</code> if a new row was retrieved; or
2675: * <p><code>false</code> if there are no more rows .
2676: * @exception DatabaseException when an error occurred during the fetch of
2677: * the next row in the resultset
2678: * @see #fetch(ResultSet, DbRowProcessor)
2679: * @since 1.0
2680: */
2681: public boolean fetch(ResultSet resultSet) throws DatabaseException {
2682: return fetch(resultSet, null);
2683: }
2684:
2685: /**
2686: * Fetches the next row of a resultset and processes it through a
2687: * <code>DbRowProcessor</code>.
2688: *
2689: * @param resultSet a valid <code>ResultSet</code> instance
2690: * @param rowProcessor a <code>DbRowProcessor</code> instance, if it's
2691: * <code>null</code> no processing will be performed on the fetched row
2692: * @return <code>true</code> if a new row was retrieved; or
2693: * <p><code>false</code> if there are no more rows .
2694: * @exception DatabaseException when an error occurred during the fetch of
2695: * the next row in the resultset
2696: * @see #fetch(ResultSet)
2697: * @see DbRowProcessor
2698: * @since 1.0
2699: */
2700: public boolean fetch(ResultSet resultSet,
2701: DbRowProcessor rowProcessor) throws DatabaseException {
2702: if (null == resultSet)
2703: throw new IllegalArgumentException(
2704: "resultSet can't be null.");
2705:
2706: try {
2707: if (resultSet.next()) {
2708: if (rowProcessor != null) {
2709: rowProcessor.processRowWrapper(resultSet);
2710: }
2711: return true;
2712: }
2713: } catch (SQLException e) {
2714: throw new RowProcessorErrorException(e);
2715: }
2716:
2717: return false;
2718: }
2719:
2720: /**
2721: * Fetches all the next rows of a resultset and processes it through a
2722: * <code>DbRowProcessor</code>.
2723: *
2724: * @param resultSet a valid <code>ResultSet</code> instance
2725: * @param rowProcessor a <code>DbRowProcessor</code> instance, if it's
2726: * <code>null</code> no processing will be performed on the fetched rows
2727: * @return <code>true</code> if rows were fetched; or
2728: * <p><code>false</code> if the resultset contained no rows.
2729: * @exception DatabaseException when an error occurred during the fetch of
2730: * the next rows in the resultset
2731: * @see DbRowProcessor
2732: * @since 1.0
2733: */
2734: public boolean fetchAll(ResultSet resultSet,
2735: DbRowProcessor rowProcessor) throws DatabaseException {
2736: if (null == rowProcessor)
2737: throw new IllegalArgumentException(
2738: "rowProcessor can't be null.");
2739:
2740: boolean result = false;
2741:
2742: while (fetch(resultSet, rowProcessor)) {
2743: result = true;
2744:
2745: if (rowProcessor != null && !rowProcessor.wasSuccessful()) {
2746: break;
2747: }
2748: }
2749:
2750: return result;
2751: }
2752:
2753: /**
2754: * Obtains a <code>DbConnection</code> of this <code>DbQueryManager</code>'s
2755: * <code>Datasource</code>. Functions exactly as the wrapped {@link
2756: * Datasource#getConnection()} method.
2757: * @see Datasource#getConnection()
2758: * @since 1.0
2759: * @exception DatabaseException see {@link Datasource#getConnection()}
2760: * @return the requested <code>DbConnection</code>
2761: */
2762: public DbConnection getConnection() throws DatabaseException {
2763: return mDatasource.getConnection();
2764: }
2765:
2766: /**
2767: * Retrieves the <code>Datasource</code> of this
2768: * <code>DbQueryManager</code>.
2769: *
2770: * @return the requested <code>Datasource</code>
2771: * @since 1.0
2772: */
2773: public Datasource getDatasource() {
2774: return mDatasource;
2775: }
2776:
2777: /**
2778: * Simply clones the instance with the default clone method. This creates
2779: * a shallow copy of all fields and the clone will in fact just be another
2780: * reference to the same underlying data. The independence of each cloned
2781: * instance is consciously not respected since they rely on resources that
2782: * can't be cloned.
2783: * @since 1.0
2784: * @return a clone of this instance
2785: */
2786: public Object clone() {
2787: try {
2788: return super .clone();
2789: } catch (CloneNotSupportedException e) {
2790: ///CLOVER:OFF
2791: // this should never happen
2792: Logger.getLogger("com.uwyn.rife.database").severe(
2793: ExceptionUtils.getExceptionStackTrace(e));
2794: return null;
2795: ///CLOVER:ON
2796: }
2797: }
2798:
2799: private void defensiveClose(InputStream stream) {
2800: if (null == stream) {
2801: return;
2802: }
2803:
2804: try {
2805: stream.close();
2806: } catch (IOException e) {
2807: // couldn't close stream since it probably already has been
2808: // closed after an exception
2809: // proceed without reporting an error message.
2810: }
2811: }
2812:
2813: private void defensiveClose(Reader reader) {
2814: if (null == reader) {
2815: return;
2816: }
2817:
2818: try {
2819: reader.close();
2820: } catch (IOException e) {
2821: // couldn't close reader since it probably already has been
2822: // closed after an exception
2823: // proceed without reporting an error message.
2824: }
2825: }
2826:
2827: private void defensiveClose(DbStatement statement) {
2828: if (null == statement) {
2829: return;
2830: }
2831:
2832: try {
2833: statement.close();
2834: } catch (DatabaseException e) {
2835: // couldn't close statement since it probably already has been
2836: // closed after an exception
2837: // proceed without reporting an error message.
2838: }
2839: }
2840: }
|