/*
* Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com)
* Licensed under the Apache License, Version 2.0 (the "License")
* $Id: DbQueryManager.java 3918 2008-04-14 17:35:35Z gbevin $
*/
package com.uwyn.rife.database;
import com.uwyn.rife.database.exceptions.DatabaseException;
import com.uwyn.rife.database.exceptions.RollbackException;
import com.uwyn.rife.database.exceptions.RowProcessorErrorException;
import com.uwyn.rife.database.queries.Query;
import com.uwyn.rife.database.queries.ReadQuery;
import com.uwyn.rife.tools.ExceptionUtils;
import com.uwyn.rife.tools.exceptions.InnerClassException;
import com.uwyn.rife.tools.InputStreamUser;
import com.uwyn.rife.tools.ReaderUser;
import com.uwyn.rife.tools.exceptions.ControlFlowRuntimeException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Logger;
/**
* This is a convenience class to make it easy to control the queries that
* handle the retrieval, storage, update and removal of data in a database.
* All queries will be executed in a connection of the <code>Datasource</code>
* that's provided to the constructor of the <code>DbQueryManager</code>.
* <p>A collection of convenience methods have been provided to quickly
* execute queries in a variety of manners without having to worry about the
* logic behind it or having to remember to close the queries at the
* appropriate moment. These methods optionally interact with the
* <code>DbPreparedStatementHandler</code> and <code>DbResultSetHandler</code>
* classes to make it possible to fully customize the executed queries. The
* following categories of worry-free methods exist:
* <ul>
* <li>{@linkplain #executeUpdate(Query) execute an update query directly}
* <li>{@linkplain #executeUpdate(Query,DbPreparedStatementHandler) execute a
* customizable update query}
* <li>{@linkplain #executeQuery(ReadQuery,DbPreparedStatementHandler) execute a
* customizable select query}
* <li>{@linkplain #executeHasResultRows(ReadQuery,DbPreparedStatementHandler)
* check the result rows of a customizable select query}
* <li>{@linkplain #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* obtain the first value of a customizable select query}
* <li>{@linkplain
* #executeFetchFirst(ReadQuery,DbRowProcessor,DbPreparedStatementHandler) fetch
* the first row of a customizable select query}
* <li>{@linkplain
* #executeFetchFirstBean(ReadQuery,Class,DbPreparedStatementHandler) fetch the
* first bean of a customizable select query}
* <li>{@linkplain
* #executeFetchAll(ReadQuery,DbRowProcessor,DbPreparedStatementHandler) fetch
* all rows of a customizable select query}
* <li>{@linkplain
* #executeFetchAllBeans(ReadQuery,Class,DbPreparedStatementHandler) fetch all
* beans of a customizable select query}
* </ul>
* <p>Lower-level methods are also available for the sake of repetitive
* code-reduction. To obtain execute regular statements directly,
* use the {@link #executeQuery(ReadQuery) executeQuery} method.
* <p>Finally, <code>since DbStatement</code> and
* <code>DbPreparedStatement</code> instances preserve a reference to their
* resultset, it's easy to iterate over the rows of a resultset with the
* {@link #fetch(ResultSet,DbRowProcessor) fetch} or {@link
* #fetchAll(ResultSet,DbRowProcessor) fetchAll} methods.
*
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
* @version $Revision: 3918 $
* @see com.uwyn.rife.database.DbPreparedStatement
* @see com.uwyn.rife.database.DbStatement
* @see com.uwyn.rife.database.DbRowProcessor
* @see com.uwyn.rife.database.DbPreparedStatementHandler
* @see com.uwyn.rife.database.DbResultSetHandler
* @see com.uwyn.rife.database.DbConnectionUser
* @since 1.0
*/
public class DbQueryManager implements Cloneable
{
private final Datasource mDatasource;
/**
* Instantiates a new <code>DbQueryManager</code> object and ties it to
* the provided datasource.
*
* @param datasource the datasource that will be used to obtain database
* connections from
* @since 1.0
*/
public DbQueryManager(Datasource datasource)
{
if (null == datasource) throw new IllegalArgumentException("datasource can't be null.");
mDatasource = datasource;
}
/**
* Safely and quickly executes an update statement. It relies on the
* wrapped {@link DbStatement#executeUpdate(String)} method, but also
* automatically closes the statement after its execution.
* <p>This method is typically used in situations where one static update
* query needs to be executed without any parametrization or other
* processing.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*int count = manager.executeUpdate("INSERT INTO person (name) VALUES ('me')");</pre>
*
* @param sql the sql query that has to be executed
* @return the row count for the executed query
* @exception DatabaseException see {@link
* DbStatement#executeUpdate(String)}
* @see DbStatement#executeUpdate(String)
* @see #executeUpdate(Query)
* @since 1.0
*/
public int executeUpdate(String sql)
throws DatabaseException
{
if (null == sql) throw new IllegalArgumentException("sql can't be null.");
DbConnection connection = getConnection();
try
{
DbStatement statement = connection.createStatement();
try
{
return statement.executeUpdate(sql);
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly executes an update statement. It relies on the
* wrapped {@link DbStatement#executeUpdate(Query)} method, but also
* automatically closes the statement after its execution.
* <p>This method is typically used in situations where one static update
* query needs to be executed without any parametrization or other
* processing.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Insert insert = new Insert(datasource);
*insert.into("person").field("name", "me");
*int count = manager.executeUpdate(insert);</pre>
*
* @param query the query builder instance that needs to be executed
* @return the row count for the executed query
* @exception DatabaseException see {@link
* DbStatement#executeUpdate(Query)}
* @see DbStatement#executeUpdate(Query)
* @see #executeUpdate(String)
* @since 1.0
*/
public int executeUpdate(Query query)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbStatement statement = connection.createStatement();
try
{
return statement.executeUpdate(query);
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
private DbPreparedStatement getPreparedStatement(Query query, DbResultSetHandler handler, DbConnection connection)
{
return mDatasource.getCapabilitiesCompensator().getCapablePreparedStatement(query, handler, connection);
}
private void executeQuery(DbPreparedStatement statement, DbPreparedStatementHandler handler)
{
if (null == handler)
{
statement.executeQuery();
}
else
{
handler.performQuery(statement);
}
}
private DbResultSet getResultSet(DbPreparedStatement statement)
{
return mDatasource.getCapabilitiesCompensator().getCapableResultSet(statement);
}
/**
* Safely execute an updates statement. It relies on the wrapped {@link
* DbPreparedStatement#executeUpdate()} method, but also automatically
* closes the statement after its execution and allows customization of
* the prepared statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>This method is typically used when you need to fully customize a
* query at runtime, but still want to benefit of a safety net that
* ensures that the allocated statement will be closed.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Insert insert = new Insert(datasource);
*insert.into("person").fieldParameter("name");
*final String name = "me";
*int count = manager.executeUpdate(insert, new DbPreparedStatementHandler() {
* public void setParameters(DbPreparedStatement statement)
* {
* statement
* .setString("name", name);
* }
* });</pre>
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the row count for the executed query
* @exception DatabaseException see {@link
* DbPreparedStatement#executeUpdate()}
* @see DbPreparedStatement#executeUpdate()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public int executeUpdate(Query query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
if (null == handler)
{
return statement.executeUpdate();
}
return handler.performUpdate(statement);
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
private boolean executeHasResultRows(DbPreparedStatement statement, DbPreparedStatementHandler handler)
{
executeQuery(statement, handler);
return getResultSet(statement).hasResultRows();
}
/**
* Safely and quickly verifies if a select query returns any rows. It
* relies on the wrapped {@link DbResultSet#hasResultRows()} method, but
* also automatically closes the statement after its execution.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select.from("person");
*boolean result = manager.executeHasResultRows(select);
*</pre>
*
* @param query the query builder instance that needs to be executed
* @return <code>true</code> when rows were returned by the query; or
* <p><code>false</code> otherwise
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#hasResultRows()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#hasResultRows()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public boolean executeHasResultRows(ReadQuery query)
throws DatabaseException
{
return executeHasResultRows(query, null);
}
/**
* Safely verifies if a customizable select query returns any rows. It
* relies on the wrapped {@link DbResultSet#hasResultRows()} method, but
* also automatically closes the statement after its execution and allows
* customization of the prepared statement through an optional instance of
* {@link DbPreparedStatementHandler}.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select.from("person").whereParameter("name", "=");
*final String name = "you";
*boolean result = manager.executeHasResultRows(select, new DbPreparedStatementHandler() {
* public void setParameters(DbPreparedStatement statement)
* {
* statement
* .setString("name", name);
* }
* });</pre>
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return <code>true</code> when rows were returned by the query; or
* <p><code>false</code> otherwise
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#hasResultRows()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#hasResultRows()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public boolean executeHasResultRows(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
boolean result = executeHasResultRows(statement, handler);
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a <code>String</code>
* from the results of a select query. It relies on the wrapped {@link
* DbResultSet#getFirstString()} method, but also automatically closes the
* statement after its execution.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select.field("name").from("person");
*String result = manager.executeGetFirstString(select);
*</pre>
*
* @param query the query builder instance that needs to be executed
* @return the first <code>String</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstString()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstString()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public String executeGetFirstString(ReadQuery query)
throws DatabaseException
{
return executeGetFirstString(query, null);
}
/**
* Safely retrieves the first cell as a <code>String</code> from the
* results of a customizable select query. It relies on the wrapped {@link
* DbResultSet#getFirstString()} method, but also automatically closes the
* statement after its execution and allows customization of the prepared
* statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select.field("first").from("person").whereParameter("last", "=");
*final String last = "Smith";
*String result = manager.executeGetFirstString(select, new DbPreparedStatementHandler() {
* public void setParameters(DbPreparedStatement statement)
* {
* statement
* .setString("last", last);
* }
* });</pre>
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first <code>String</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstString()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstString()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public String executeGetFirstString(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
String result = null;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstString();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a <code>boolean</code>
* from the results of a select query. It relies on the wrapped {@link
* DbResultSet#getFirstBoolean()} method, but also automatically closes
* the statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @return the first <code>boolean</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstBoolean()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstBoolean()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public boolean executeGetFirstBoolean(ReadQuery query)
throws DatabaseException
{
return executeGetFirstBoolean(query, null);
}
/**
* Safely retrieves the first cell as a <code>boolean</code> from the
* results of a customizable select query. It relies on the wrapped {@link
* DbResultSet#getFirstBoolean()} method, but also automatically closes
* the statement after its execution and allows customization of the
* prepared statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first <code>boolean</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstBoolean()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstBoolean()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public boolean executeGetFirstBoolean(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
boolean result = false;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstBoolean();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a <code>byte</code> from
* the results of a select query. It relies on the wrapped {@link
* DbResultSet#getFirstByte()} method, but also automatically closes the
* statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @return the first <code>byte</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstByte()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstByte()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public byte executeGetFirstByte(ReadQuery query)
throws DatabaseException
{
return executeGetFirstByte(query, null);
}
/**
* Safely retrieves the first cell as a <code>byte</code> from the results
* of a customizable select query. It relies on the wrapped {@link
* DbResultSet#getFirstByte()} method, but also automatically closes the
* statement after its execution and allows customization of the prepared
* statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first <code>byte</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstByte()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstByte()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public byte executeGetFirstByte(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
byte result = -1;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstByte();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a <code>short</code>
* from the results of a select query. It relies on the wrapped {@link
* DbResultSet#getFirstShort()} method, but also automatically closes the
* statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @return the first <code>short</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstShort()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstShort()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public short executeGetFirstShort(ReadQuery query)
throws DatabaseException
{
return executeGetFirstShort(query, null);
}
/**
* Safely retrieves the first cell as a <code>short</code> from the
* results of a customizable select query. It relies on the wrapped {@link
* DbResultSet#getFirstShort()} method, but also automatically closes the
* statement after its execution and allows customization of the prepared
* statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first <code>short</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstShort()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstShort()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public short executeGetFirstShort(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
short result = -1;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstShort();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a <code>int</code> from
* the results of a select query. It relies on the wrapped {@link
* DbResultSet#getFirstInt()} method, but also automatically closes the
* statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @return the first <code>int</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link DbResultSet#getFirstInt()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstInt()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public int executeGetFirstInt(ReadQuery query)
throws DatabaseException
{
return executeGetFirstInt(query, null);
}
/**
* Safely retrieves the first cell as a <code>int</code> from the results
* of a customizable select query. It relies on the wrapped {@link
* DbResultSet#getFirstInt()} method, but also automatically closes the
* statement after its execution and allows customization of the prepared
* statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first <code>int</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link DbResultSet#getFirstInt()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstInt()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public int executeGetFirstInt(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
int result = -1;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstInt();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a <code>long</code> from
* the results of a select query. It relies on the wrapped {@link
* DbResultSet#getFirstLong()} method, but also automatically closes the
* statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @return the first <code>long</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstLong()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstLong()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public long executeGetFirstLong(ReadQuery query)
throws DatabaseException
{
return executeGetFirstLong(query, null);
}
/**
* Safely retrieves the first cell as a <code>long</code> from the results
* of a customizable select query. It relies on the wrapped {@link
* DbResultSet#getFirstLong()} method, but also automatically closes the
* statement after its execution and allows customization of the prepared
* statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first <code>long</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstLong()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstLong()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public long executeGetFirstLong(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
long result = -1;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstLong();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a <code>float</code>
* from the results of a select query. It relies on the wrapped {@link
* DbResultSet#getFirstFloat()} method, but also automatically closes the
* statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @return the first <code>float</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstFloat()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstFloat()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public float executeGetFirstFloat(ReadQuery query)
throws DatabaseException
{
return executeGetFirstFloat(query, null);
}
/**
* Safely retrieves the first cell as a <code>float</code> from the
* results of a customizable select query. It relies on the wrapped {@link
* DbResultSet#getFirstFloat()} method, but also automatically closes the
* statement after its execution and allows customization of the prepared
* statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first <code>float</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstFloat()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstFloat()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public float executeGetFirstFloat(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
float result = -1;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstFloat();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a <code>double</code>
* from the results of a select query. It relies on the wrapped {@link
* DbResultSet#getFirstDouble()} method, but also automatically closes the
* statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @return the first <code>double</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstDouble()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstDouble()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public double executeGetFirstDouble(ReadQuery query)
throws DatabaseException
{
return executeGetFirstDouble(query, null);
}
/**
* Safely retrieves the first cell as a <code>double</code> from the
* results of a customizable select query. It relies on the wrapped {@link
* DbResultSet#getFirstDouble()} method, but also automatically closes the
* statement after its execution and allows customization of the prepared
* statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first <code>double</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstDouble()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstDouble()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public double executeGetFirstDouble(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
double result = -1;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstDouble();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a <code>byte</code>
* array from the results of a select query. It relies on the wrapped
* {@link DbResultSet#getFirstBytes()} method, but also automatically
* closes the statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @return the first <code>byte</code> array in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstBytes()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstBytes()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public byte[] executeGetFirstBytes(ReadQuery query)
throws DatabaseException
{
return executeGetFirstBytes(query, null);
}
/**
* Safely retrieves the first cell as a <code>byte</code> array from the
* results of a customizable select query. It relies on the wrapped {@link
* DbResultSet#getFirstBytes()} method, but also automatically closes the
* statement after its execution and allows customization of the prepared
* statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first <code>byte</code> array in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstBytes()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstBytes()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public byte[] executeGetFirstBytes(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
byte[] result = null;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstBytes();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a sql <code>Date</code>
* from the results of a select query. It relies on the wrapped {@link
* DbResultSet#getFirstDate()} method, but also automatically closes the
* statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @return the first sql <code>Date</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstDate()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstDate()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public java.sql.Date executeGetFirstDate(ReadQuery query)
throws DatabaseException
{
return executeGetFirstDate(query, (DbPreparedStatementHandler)null);
}
/**
* Safely retrieves the first cell as a sql <code>Date</code> from the
* results of a customizable select query. It relies on the wrapped {@link
* DbResultSet#getFirstDate()} method, but also automatically closes the
* statement after its execution and allows customization of the prepared
* statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first sql <code>Date</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstDate()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstDate()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public java.sql.Date executeGetFirstDate(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
java.sql.Date result = null;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstDate();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a sql <code>Date</code>
* from the results of a select query. It relies on the wrapped {@link
* DbResultSet#getFirstDate(Calendar)} method, but also automatically
* closes the statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param cal the <code>Calendar</code> object to use in constructing the
* date
* @return the first sql <code>Date</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstDate(Calendar)}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstDate(Calendar)
* @see DbPreparedStatementHandler
* @since 1.0
*/
public java.sql.Date executeGetFirstDate(ReadQuery query, Calendar cal)
throws DatabaseException
{
return executeGetFirstDate(query, cal, null);
}
/**
* Safely retrieves the first cell as a sql <code>Date</code> from the
* results of a customizable select query. It relies on the wrapped {@link
* DbResultSet#getFirstDate(Calendar)} method, but also automatically
* closes the statement after its execution and allows customization of
* the prepared statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param cal the <code>Calendar</code> object to use in constructing the
* date
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first sql <code>Date</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstDate(Calendar)}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstDate(Calendar)
* @see DbPreparedStatementHandler
* @since 1.0
*/
public java.sql.Date executeGetFirstDate(ReadQuery query, Calendar cal, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
java.sql.Date result = null;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstDate(cal);
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a sql <code>Time</code>
* from the results of a select query. It relies on the wrapped {@link
* DbResultSet#getFirstTime()} method, but also automatically closes the
* statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @return the first sql <code>Time</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstTime()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstTime()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public java.sql.Time executeGetFirstTime(ReadQuery query)
throws DatabaseException
{
return executeGetFirstTime(query, (DbPreparedStatementHandler)null);
}
/**
* Safely retrieves the first cell as a sql <code>Time</code> from the
* results of a customizable select query. It relies on the wrapped {@link
* DbResultSet#getFirstTime()} method, but also automatically closes the
* statement after its execution and allows customization of the prepared
* statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first sql <code>Time</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstTime()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstTime()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public java.sql.Time executeGetFirstTime(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
java.sql.Time result = null;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstTime();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a sql <code>Time</code>
* from the results of a select query. It relies on the wrapped {@link
* DbResultSet#getFirstTime(Calendar)} method, but also automatically
* closes the statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param cal the <code>Calendar</code> object to use in constructing the
* time
* @return the first sql <code>Time</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstTime(Calendar)}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstTime(Calendar)
* @see DbPreparedStatementHandler
* @since 1.0
*/
public java.sql.Time executeGetFirstTime(ReadQuery query, Calendar cal)
throws DatabaseException
{
return executeGetFirstTime(query, cal, null);
}
/**
* Safely retrieves the first cell as a sql <code>Time</code> from the
* results of a customizable select query. It relies on the wrapped {@link
* DbResultSet#getFirstTime(Calendar)} method, but also automatically
* closes the statement after its execution and allows customization of
* the prepared statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param cal the <code>Calendar</code> object to use in constructing the
* time
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first sql <code>Time</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstTime(Calendar)}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstTime(Calendar)
* @see DbPreparedStatementHandler
* @since 1.0
*/
public java.sql.Time executeGetFirstTime(ReadQuery query, Calendar cal, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
java.sql.Time result = null;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstTime(cal);
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a sql
* <code>Timestamp</code> from the results of a select query. It relies on
* the wrapped {@link DbResultSet#getFirstTimestamp()} method, but also
* automatically closes the statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @return the first sql <code>Timestamp</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstTimestamp()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstTimestamp()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public java.sql.Timestamp executeGetFirstTimestamp(ReadQuery query)
throws DatabaseException
{
return executeGetFirstTimestamp(query, (DbPreparedStatementHandler)null);
}
/**
* Safely retrieves the first cell as a sql <code>Timestamp</code> from
* the results of a customizable select query. It relies on the wrapped
* {@link DbResultSet#getFirstTimestamp()} method, but also automatically
* closes the statement after its execution and allows customization of
* the prepared statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first sql <code>Timestamp</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstTimestamp()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstTimestamp()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public java.sql.Timestamp executeGetFirstTimestamp(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
java.sql.Timestamp result = null;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstTimestamp();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as a sql
* <code>Timestamp</code> from the results of a select query. It relies on
* the wrapped {@link DbResultSet#getFirstTimestamp(Calendar)} method, but
* also automatically closes the statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param cal the <code>Calendar</code> object to use in constructing the
* timestamp
* @return the first sql <code>Timestamp</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstTimestamp(Calendar)}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstTimestamp(Calendar)
* @see DbPreparedStatementHandler
* @since 1.0
*/
public java.sql.Timestamp executeGetFirstTimestamp(ReadQuery query, Calendar cal)
throws DatabaseException
{
return executeGetFirstTimestamp(query, cal, null);
}
/**
* Safely retrieves the first cell as a sql <code>Timestamp</code> from
* the results of a customizable select query. It relies on the wrapped
* {@link DbResultSet#getFirstTimestamp(Calendar)} method, but also
* automatically closes the statement after its execution and allows
* customization of the prepared statement through an optional instance of
* {@link DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param cal the <code>Calendar</code> object to use in constructing the
* timestamp
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the first sql <code>Timestamp</code> in the query's resultset
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstTimestamp(Calendar)}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstTimestamp(Calendar)
* @see DbPreparedStatementHandler
* @since 1.0
*/
public java.sql.Timestamp executeGetFirstTimestamp(ReadQuery query, Calendar cal, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
java.sql.Timestamp result = null;
if (executeHasResultRows(statement, handler))
{
result = getResultSet(statement).getFirstTimestamp(cal);
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as an ASCII
* <code>InputStream</code> from the results of a select query. It relies
* on the wrapped {@link DbResultSet#getFirstAsciiStream()} method, but
* also automatically closes the statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param user an instance of <code>InputStreamUser</code>
* that contains the logic that will be executed with this stream
* @return the return value from the <code>useInputStream</code> method of
* the provided <code>InputStreamUser</code> instance
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstAsciiStream()}
* @exception InnerClassException when errors occurs inside the
* <code>InputStreamUser</code>
* @see InputStreamUser
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstAsciiStream()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public <ResultType> ResultType executeUseFirstAsciiStream(ReadQuery query, InputStreamUser user)
throws DatabaseException, InnerClassException
{
return (ResultType)executeUseFirstAsciiStream(query, user, null);
}
/**
* Safely retrieves the first cell as an ASCII <code>InputStream</code>
* from the results of a customizable select query. It relies on the
* wrapped {@link DbResultSet#getFirstAsciiStream()} method, but also
* automatically closes the statement after its execution and allows
* customization of the prepared statement through an optional instance of
* {@link DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param user an instance of <code>InputStreamUser</code>
* that contains the logic that will be executed with this stream
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the return value from the <code>useInputStream</code> method of
* the provided <code>InputStreamUser</code> instance
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstAsciiStream()}
* @exception InnerClassException when errors occurs inside the
* <code>InputStreamUser</code>
* @see InputStreamUser
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstAsciiStream()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public <ResultType> ResultType executeUseFirstAsciiStream(ReadQuery query, InputStreamUser user, DbPreparedStatementHandler handler)
throws DatabaseException, InnerClassException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
if (null == user) throw new IllegalArgumentException("user can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
InputStream stream = null;
try
{
statement.setFetchSize(1);
if (executeHasResultRows(statement, handler))
{
stream = getResultSet(statement).getFirstAsciiStream();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return (ResultType)user.useInputStream(stream);
}
finally
{
defensiveClose(stream);
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as an character
* <code>Reader</code> from the results of a select query. It relies on
* the wrapped {@link DbResultSet#getFirstCharacterStream()} method, but
* also automatically closes the statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param user an instance of <code>ReaderUser</code>
* that contains the logic that will be executed with this reader
* @return the return value from the <code>useReader</code> method of
* the provided <code>ReaderUser</code> instance
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstCharacterStream()}
* @exception InnerClassException when errors occurs inside the
* <code>ReaderUser</code>
* @see ReaderUser
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstCharacterStream()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public <ResultType> ResultType executeUseFirstCharacterStream(ReadQuery query, ReaderUser user)
throws DatabaseException, InnerClassException
{
return (ResultType)executeUseFirstCharacterStream(query, user, null);
}
/**
* Safely retrieves the first cell as an character <code>Reader</code>
* from the results of a customizable select query. It relies on the
* wrapped {@link DbResultSet#getFirstCharacterStream()} method, but also
* automatically closes the statement after its execution and allows
* customization of the prepared statement through an optional instance of
* {@link DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param user an instance of <code>ReaderUser</code>
* that contains the logic that will be executed with this reader
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the return value from the <code>useReader</code> method of
* the provided <code>ReaderUser</code> instance
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstCharacterStream()}
* @exception InnerClassException when errors occurs inside the
* <code>ReaderUser</code>
* @see ReaderUser
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstCharacterStream()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public <ResultType> ResultType executeUseFirstCharacterStream(ReadQuery query, ReaderUser user, DbPreparedStatementHandler handler)
throws DatabaseException, InnerClassException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
if (null == user) throw new IllegalArgumentException("user can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
Reader reader = null;
try
{
statement.setFetchSize(1);
if (executeHasResultRows(statement, handler))
{
reader = getResultSet(statement).getFirstCharacterStream();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return (ResultType)user.useReader(reader);
}
finally
{
defensiveClose(reader);
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly retrieves the first cell as an binary
* <code>InputStream</code> from the results of a select query. It relies
* on the wrapped {@link DbResultSet#getFirstBinaryStream()} method, but
* also automatically closes the statement after its execution.
* <p>Refer to {@link #executeGetFirstString(ReadQuery) executeGetFirstString}
* for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param user an instance of <code>InputStreamUser</code>
* that contains the logic that will be executed with this stream
* @return the return value from the <code>useInputStream</code> method of
* the provided <code>InputStreamUser</code> instance
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstBinaryStream()}
* @exception InnerClassException when errors occurs inside the
* <code>InputStreamUser</code>
* @see InputStreamUser
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstBinaryStream()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public <ResultType> ResultType executeUseFirstBinaryStream(ReadQuery query, InputStreamUser user)
throws DatabaseException, InnerClassException
{
return (ResultType)executeUseFirstBinaryStream(query, user, null);
}
/**
* Safely retrieves the first cell as an binary <code>InputStream</code>
* from the results of a customizable select query. It relies on the
* wrapped {@link DbResultSet#getFirstBinaryStream()} method, but also
* automatically closes the statement after its execution and allows
* customization of the prepared statement through an optional instance of
* {@link DbPreparedStatementHandler}.
* <p>Refer to {@link
* #executeGetFirstString(ReadQuery,DbPreparedStatementHandler)
* executeGetFirstString} for an example code snippet, it's 100% analogue.
*
* @param query the query builder instance that needs to be executed
* @param user an instance of <code>InputStreamUser</code>
* that contains the logic that will be executed with this stream
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the return value from the <code>useInputStream</code> method of
* the provided <code>InputStreamUser</code> instance
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* DbResultSet#getFirstBinaryStream()}
* @exception InnerClassException when errors occurs inside the
* <code>InputStreamUser</code>
* @see InputStreamUser
* @see DbPreparedStatement#executeQuery()
* @see DbResultSet#getFirstBinaryStream()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public <ResultType> ResultType executeUseFirstBinaryStream(ReadQuery query, InputStreamUser user, DbPreparedStatementHandler handler)
throws DatabaseException, InnerClassException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
if (null == user) throw new IllegalArgumentException("user can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
InputStream stream = null;
try
{
statement.setFetchSize(1);
if (executeHasResultRows(statement, handler))
{
stream = getResultSet(statement).getFirstBinaryStream();
}
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return (ResultType)user.useInputStream(stream);
}
finally
{
defensiveClose(stream);
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly fetches the first row from the results of a select
* query. It relies on the wrapped {@link
* #fetch(ResultSet, DbRowProcessor)} method, but automatically closes the
* statement after its execution.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select.from("person").where("name", "=", "me");
*DbRowProcessor processor = new YourProcessor();
*boolean result = manager.executeFetchFirst(select, processor);</pre>
*
* @param query the query builder instance that needs to be executed
* @param rowProcessor a <code>DbRowProcessor</code> instance, if it's
* <code>null</code> no processing will be performed on the fetched row
* @return <code>true</code> if a row was retrieved; or
* <p><code>false</code> if there are no more rows .
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* #fetch(ResultSet, DbRowProcessor)}
* @see #fetch(ResultSet, DbRowProcessor)
* @see DbRowProcessor
* @since 1.0
*/
public boolean executeFetchFirst(ReadQuery query, DbRowProcessor rowProcessor)
throws DatabaseException
{
return executeFetchFirst(query, rowProcessor, null);
}
/**
* Safely fetches the first row from the results of a customizable select
* query. It relies on the wrapped {@link
* #fetch(ResultSet, DbRowProcessor)} method, but also automatically
* closes the statement after its execution and allows customization of
* the prepared statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select.from("person").whereParameter("name", "=");
*DbRowProcessor processor = new YourProcessor();
*final String name = "you";
*boolean result = manager.executeFetchFirst(select, processor, new DbPreparedStatementHandler() {
* public void setParameters(DbPreparedStatement statement)
* {
* statement
* .setString("name", name);
* }
* });</pre>
*
* @param query the query builder instance that needs to be executed
* @param rowProcessor a <code>DbRowProcessor</code> instance, if it's
* <code>null</code> no processing will be performed on the fetched row
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return <code>true</code> if a row was retrieved; or
* <p><code>false</code> if there are no more rows .
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* #fetch(ResultSet, DbRowProcessor)}
* @see #fetch(ResultSet, DbRowProcessor)
* @see DbRowProcessor
* @since 1.0
*/
public boolean executeFetchFirst(ReadQuery query, DbRowProcessor rowProcessor, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
statement.setFetchSize(1);
executeQuery(statement, handler);
boolean result = fetch(getResultSet(statement), rowProcessor);
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly fetches the first bean instance from the results of
* a select query. It relies on the wrapped {@link
* #executeFetchFirst(ReadQuery, DbRowProcessor)} method, but automatically
* uses an appropriate {@link DbBeanFetcher} instance and returns the
* resulting bean.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select.from("person").fields(Person.class);
*Person person = manager.executeFetchFirstBean(select, Person.class);</pre>
*
* @param query the query builder instance that needs to be executed
* @param beanClass the class of the bean
* @return <code>true</code> if a row was retrieved; or
* <p><code>false</code> if there are no more rows .
* @exception DatabaseException see {@link DbBeanFetcher} and {@link
* #executeFetchFirst(ReadQuery, DbRowProcessor)}
* @see #executeFetchFirst(ReadQuery, DbRowProcessor)
* @see DbBeanFetcher
* @since 1.0
*/
public <BeanType> BeanType executeFetchFirstBean(ReadQuery query, Class<BeanType> beanClass)
throws DatabaseException
{
return executeFetchFirstBean(query, beanClass, null);
}
/**
* Safely fetches the first bean instance from the results of a
* customizable select query. It relies on the wrapped {@link
* #executeFetchFirst(ReadQuery, DbRowProcessor)} method, but automatically
* uses an appropriate {@link DbBeanFetcher} instance, returns the
* resulting bean and allows customization of the prepared statement
* through an optional instance of {@link DbPreparedStatementHandler}.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select.from("person").fields(Person.class).whereParameter("name", "=");
*final String name = "you";
*Person person = manager.executeFetchFirstBean(select, Person.class, new DbPreparedStatementHandler() {
* public void setParameters(DbPreparedStatement statement)
* {
* statement
* .setString("name", name);
* }
* });</pre>
*
* @param query the query builder instance that needs to be executed
* @param beanClass the class of the bean
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return <code>true</code> if a row was retrieved; or
* <p><code>false</code> if there are no more rows .
* @exception DatabaseException see {@link DbBeanFetcher} and {@link
* #executeFetchFirst(ReadQuery, DbRowProcessor)}
* @see #executeFetchFirst(ReadQuery, DbRowProcessor)
* @see DbBeanFetcher
* @since 1.0
*/
public <BeanType> BeanType executeFetchFirstBean(ReadQuery query, Class<BeanType> beanClass, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbBeanFetcher<BeanType> bean_fetcher = new DbBeanFetcher<BeanType>(getDatasource(), beanClass);
if (executeFetchFirst(query, bean_fetcher, handler))
{
return bean_fetcher.getBeanInstance();
}
return null;
}
/**
* Safely and quickly fetches all the rows from the results of a select
* query. It relies on the wrapped {@link
* #fetchAll(ResultSet, DbRowProcessor)} method, but automatically closes
* the statement after its execution.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select.from("person").where("gender", "=", "m");
*DbRowProcessor processor = new YourProcessor();
*boolean result = manager.executeFetchAll(select, processor);</pre>
*
* @param query the query builder instance that needs to be executed
* @param rowProcessor a <code>DbRowProcessor</code> instance, if it's
* <code>null</code> no processing will be performed on the fetched rows
* @return <code>true</code> if rows were retrieved; or
* <p><code>false</code> if there are no more rows .
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* #fetchAll(ResultSet, DbRowProcessor)}
* @see #fetchAll(ResultSet, DbRowProcessor)
* @see DbRowProcessor
* @since 1.0
*/
public boolean executeFetchAll(ReadQuery query, DbRowProcessor rowProcessor)
throws DatabaseException
{
return executeFetchAll(query, rowProcessor, null);
}
/**
* Safely fetches all the rows from the results of a customizable select
* query. It relies on the wrapped {@link
* #fetchAll(ResultSet, DbRowProcessor)} method, but also automatically
* closes the statement after its execution and allows customization of
* the prepared statement through an optional instance of {@link
* DbPreparedStatementHandler}.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select.from("person").whereParameter("gender", "=");
*DbRowProcessor processor = new YourProcessor();
*final String name = "m";
*boolean result = manager.executeFetchAll(select, processor, new DbPreparedStatementHandler() {
* public void setParameters(DbPreparedStatement statement)
* {
* statement
* .setString("gender", name);
* }
* });</pre>
*
* @param query the query builder instance that needs to be executed
* @param rowProcessor a <code>DbRowProcessor</code> instance, if it's
* <code>null</code> no processing will be performed on the fetched row
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return <code>true</code> if rows were retrieved; or
* <p><code>false</code> if there are no more rows .
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}and {@link
* #fetchAll(ResultSet, DbRowProcessor)}
* @see #fetchAll(ResultSet, DbRowProcessor)
* @see DbRowProcessor
* @since 1.0
*/
public boolean executeFetchAll(ReadQuery query, DbRowProcessor rowProcessor, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
executeQuery(statement, handler);
boolean result = fetchAll(getResultSet(statement), rowProcessor);
if (handler != null)
{
try
{
handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return result;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Safely and quickly fetches the all the bean instances from the results
* of a select query. It relies on the wrapped {@link
* #executeFetchAll(ReadQuery, DbRowProcessor)} method, but automatically
* uses an appropriate {@link DbBeanFetcher} instance and returns the
* results.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select.from("person").fields(Person.class).where("gender", "=", "m");
*List persons = manager.executeFetchAllBeans(select, Person.class);</pre>
*
* @param query the query builder instance that needs to be executed
* @param beanClass the class of the bean
* @return <code>a List instance with all the beans, the list is empty if
* no beans could be returned</code>
* @exception DatabaseException see {@link DbBeanFetcher} and {@link
* #executeFetchAll(ReadQuery, DbRowProcessor)}
* @see #executeFetchAll(ReadQuery, DbRowProcessor)
* @see DbBeanFetcher
* @since 1.0
*/
public <BeanType> List<BeanType> executeFetchAllBeans(ReadQuery query, Class<BeanType> beanClass)
throws DatabaseException
{
return executeFetchAllBeans(query, beanClass, null);
}
/**
* Safely fetches the all the bean instances from the results of a
* customizable select query. It relies on the wrapped {@link
* #executeFetchAll(ReadQuery, DbRowProcessor)} method, but automatically
* uses an appropriate {@link DbBeanFetcher} instance, returns the results
* and allows customization of the prepared statement through an optional
* instance of {@link DbPreparedStatementHandler}.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select.from("person").fields(Person.class).whereParameter("gender", "=");
*final String name = "m";
*List persons = manager.executeFetchAllBeans(select, Person.class, new DbPreparedStatementHandler() {
* public void setParameters(DbPreparedStatement statement)
* {
* statement
* .setString("gender", name);
* }
* });</pre>
*
* @param query the query builder instance that needs to be executed
* @param beanClass the class of the bean
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return <code>a List instance with all the beans, the list is empty if
* no beans could be returned</code>
* @exception DatabaseException see {@link DbBeanFetcher} and {@link
* #executeFetchAll(ReadQuery, DbRowProcessor)}
* @see #executeFetchAll(ReadQuery, DbRowProcessor)
* @see DbBeanFetcher
* @since 1.0
*/
public <BeanType> List<BeanType> executeFetchAllBeans(ReadQuery query, Class<BeanType> beanClass, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbBeanFetcher<BeanType> bean_fetcher = new DbBeanFetcher<BeanType>(getDatasource(), beanClass, true);
executeFetchAll(query, bean_fetcher, handler);
return bean_fetcher.getCollectedInstances();
}
/**
* Executes a customizable select statement. It relies on the wrapped
* {@link DbPreparedStatement#executeQuery()} method, but also
* automatically closes the statement after its execution and allows
* complete customization of the prepared statement through an optional
* instance of {@link DbPreparedStatementHandler}.
* <p>This method is typically used when you need to fully customize a
* query at runtime, but still want to benefit of a safety net that
* ensures that the allocated statement will be closed. Often another more
* specialized method in this class will already serve your needs, so be
* sure to verify that you actually need to intervene on every front.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select
* .field("first")
* .field("last")
* .from("person")
* .whereParameter("name", "=");
*final String name = "you";
*String result = (String)manager.executeQuery(select, new DbPreparedStatementHandler() {
* public void setParameters(DbPreparedStatement statement)
* {
* statement
* .setString("name", name);
* }
*
* public Object concludeResults(DbResultSet resultset)
* throws SQLException
* {
* return resultset.getString("first")+" "+resultset.getString("last");
* }
* });</pre>
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code>DbPreparedStatementHandler</code>
* that will be used to customize the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the object that was returned by the overridden {@link
* DbResultSetHandler#concludeResults(DbResultSet) concludeResults}
* method; or
* <p><code>null</code> if this method wasn't overridden
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}
* @see DbPreparedStatement#executeQuery()
* @see DbPreparedStatementHandler
* @since 1.0
*/
public <ResultType> ResultType executeQuery(ReadQuery query, DbPreparedStatementHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
executeQuery(statement, handler);
if (null == handler)
{
return null;
}
try
{
return (ResultType)handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Executes a select statement and handle the results in a custom fashion.
* It relies on the wrapped {@link DbPreparedStatement#executeQuery()}
* method, but also automatically closes the statement after its execution
* and allows interaction with the resultset through an optional instance
* of {@link DbResultSetHandler}.
* <p>This method is typically used when you need to interact with the
* results of a query, but still want to benefit of a safety net that
* ensures that the allocated statement will be closed. Often another more
* specialized method in this class will already serve your needs, so be
* sure to verify that there isn't another one that's better suited.
* <h3>Example</h3>
* <pre>DbQueryManager manager = new DbQueryManager(datasource);
*Select select = new Select(datasource);
*select
* .field("first")
* .field("last")
* .from("person");
*String result = (String)manager.executeQuery(select, new DbResultSetHandler() {
* public Object concludeResults(DbResultSet resultset)
* throws SQLException
* {
* return resultset.getString("first")+" "+resultset.getString("last");
* }
* });</pre>
*
* @param query the query builder instance that needs to be executed
* @param handler an instance of <code><code>DbResultSetHandler</code></code>
* that will be used to handle the results of the query execution; or
* <code>null</code> if you don't want to customize it at all
* @return the object that was returned by the overridden {@link
* DbResultSetHandler#concludeResults(DbResultSet) concludeResults}
* method; or
* <p><code>null</code> if this method wasn't overridden
* @exception DatabaseException see {@link
* DbPreparedStatement#executeQuery()}
* @see DbPreparedStatement#executeQuery()
* @see DbResultSetHandler
* @since 1.0
*/
public <ResultType> ResultType executeQuery(ReadQuery query, DbResultSetHandler handler)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbConnection connection = getConnection();
try
{
DbPreparedStatement statement = getPreparedStatement(query, handler, connection);
try
{
executeQuery(statement, null);
if (handler != null)
{
try
{
return (ResultType)handler.concludeResults(getResultSet(statement));
}
catch (SQLException e)
{
statement.handleException();
throw new DatabaseException(e);
}
}
return null;
}
finally
{
defensiveClose(statement);
}
}
finally
{
connection.close();
}
}
/**
* Reserves a database connection for a this particular thread for all the
* instructions that are executed in the provided {@link DbConnectionUser}
* instance.
* <p>This is typically used to ensure that a series of operations is done
* with the same connection, even though a database pool is used in the
* background.
* <h3>Example</h3>
* <pre>Person person;
*final Insert store_data = new Insert(datasource).into("person").fields(person);
*final Select get_last_id = new Select(datasource).from("person").field("LAST_INSERT_ID()");
*final DbQueryManager manager = new DbQueryManager(datasource);
*int id = ((Integer)manager.reserveConnection(new DbConnectionUser() {
* public Integer useConnection(DbConnection connection)
* {
* manager.executeUpdate(store_data);
* return new Integer(manager.executeGetFirstInt(get_last_id));
* }
* })).intValue();</pre>
*
* @param user an instance of <code>DbConnectionUser</code> that contains
* the logic that will be executed
* @return the return value from the <code>useConnection</code> method of
* the provided <code>DbConnectionUser</code> instance
* @exception DatabaseException when errors occurs during the reservation
* of a connection for this thread
* @exception InnerClassException when errors occurs inside the
* <code>DbConnectionUser</code>
* @see DbConnectionUser#useConnection(DbConnection)
* @since 1.0
*/
public <ResultType> ResultType reserveConnection(DbConnectionUser user)
throws InnerClassException, DatabaseException
{
if (null == user) throw new IllegalArgumentException("user can't be null.");
DbConnection connection = mDatasource.getConnection();
ConnectionPool pool = mDatasource.getPool();
synchronized (pool)
{
boolean does_threadconnection_exist = pool.hasThreadConnection(Thread.currentThread());
try
{
if (!does_threadconnection_exist) pool.registerThreadConnection(Thread.currentThread(), connection);
return (ResultType)user.useConnection(connection);
}
finally
{
if (!does_threadconnection_exist) pool.unregisterThreadConnection(Thread.currentThread());
}
}
}
/**
* Ensures that all the instructions that are executed in the provided
* {@link DbTransactionUser} instance are executed inside a transaction
* and committed afterwards. This doesn't mean that a new transaction will
* always be created. If a transaction is already active, it will simply
* be re-used. The commit will also only be take place if a new
* transaction has actually been started, otherwise it's the
* responsibility of the enclosing code to execute the commit. If an
* runtime exception occurs during the execution and a new transaction has
* been started beforehand, it will be automatically rolled back.
* <p>If you need to explicitly roll back an active transaction, use the
* {@link DbTransactionUser#rollback() rollback} method of the
* <code>DbTransactionUser</code> class. If you use a regular rollback
* method, it's possible that you're inside a nested transaction executed
* and that after the rollback, other logic continues to be executed
* outside the transaction. Using the correct {@link
* DbTransactionUser#rollback() rollback} method, stops the execution of
* the active <code>DbTransactionUser</code> and breaks out of any number
* of them nesting.
* <p>It's recommended to always use transactions through this method
* since it ensures that transactional code can be re-used and enclosed in
* other transactional code. Correctly using the regular
* transaction-related methods requires great care and planning and often
* results in error-prone and not reusable code.
* <h3>Example</h3>
* <pre>final Insert insert = new Insert(mDatasource).into("valuelist").field("value", 232);
*final DbQueryManager manager = new DbQueryManager(datasource);
*manager.inTransaction(new DbTransactionUserWithoutResult() {
* public void useTransactionWithoutResult()
* throws InnerClassException
* {
* manager.executeUpdate(insert);
* manager.executeUpdate(insert);
* }
* });
*</pre>
*
* @param user an instance of <code>DbTransactionUser</code> that contains
* the logic that will be executed
* @return the return value from the <code>useTransaction</code> method of
* the provided <code>DbTransactionUser</code> instance
* @exception DatabaseException when errors occurs during the handling of
* the transaction
* @exception InnerClassException when errors occurs inside the
* <code>DbTransactionUser</code>
* @see DbTransactionUser#useTransaction()
* @see DbTransactionUserWithoutResult#useTransactionWithoutResult()
* @since 1.0
*/
public <ResultType> ResultType inTransaction(DbTransactionUser user)
throws InnerClassException, DatabaseException
{
boolean started_transaction = false;
DbConnection connection = null;
try
{
synchronized (mDatasource)
{
connection = mDatasource.getConnection();
int isolation = user.getTransactionIsolation();
if (isolation != -1)
{
connection.setTransactionIsolation(isolation);
}
started_transaction = connection.beginTransaction();
}
ResultType result = (ResultType)user.useTransaction();
if (started_transaction)
{
connection.commit();
if (!mDatasource.isPooled())
{
connection.close();
}
}
return result;
}
catch (RollbackException e)
{
if (connection != null)
{
connection.rollback();
if (!mDatasource.isPooled())
{
connection.close();
}
}
if (started_transaction)
{
return (ResultType)null;
}
else
{
throw e;
}
}
catch (RuntimeException e)
{
if (started_transaction &&
connection != null)
{
try
{
if (e instanceof ControlFlowRuntimeException)
{
connection.commit();
}
else
{
connection.rollback();
if (!mDatasource.isPooled())
{
connection.close();
}
}
}
catch (DatabaseException e2)
{
// nothing that can be done about this
// the connection is probably closed since
// a database error occurred
}
}
throw e;
}
catch (Error e)
{
if (started_transaction &&
connection != null)
{
try
{
connection.rollback();
if (!mDatasource.isPooled())
{
connection.close();
}
}
catch (DatabaseException e2)
{
// nothing that can be done about this
// the connection is probably closed since
// a database error occurred
}
}
throw e;
}
}
/**
* Executes a query statement in a connection of this
* <code>DbQueryManager</code>'s <code>Datasource</code>. Functions
* exactly as the wrapped {@link DbStatement#executeQuery(ReadQuery)} method.
* <p>Note that the statement will not be automatically closed since using
* this method implies that you still have to work with the resultset.
*
* @param query the query builder instance that should be executed
* @return the statement that has been executed
* @exception DatabaseException see {@link DbStatement#executeQuery(ReadQuery)}
* @see DbStatement#executeQuery(ReadQuery)
* @since 1.0
*/
public DbStatement executeQuery(ReadQuery query)
throws DatabaseException
{
if (null == query) throw new IllegalArgumentException("query can't be null.");
DbStatement statement = getConnection().createStatement();
statement.executeQuery(query);
return statement;
}
/**
* Fetches the next row of a resultset without processing it in any way.
*
* @param resultSet a valid <code>ResultSet</code> instance
* @return <code>true</code> if a new row was retrieved; or
* <p><code>false</code> if there are no more rows .
* @exception DatabaseException when an error occurred during the fetch of
* the next row in the resultset
* @see #fetch(ResultSet, DbRowProcessor)
* @since 1.0
*/
public boolean fetch(ResultSet resultSet)
throws DatabaseException
{
return fetch(resultSet, null);
}
/**
* Fetches the next row of a resultset and processes it through a
* <code>DbRowProcessor</code>.
*
* @param resultSet a valid <code>ResultSet</code> instance
* @param rowProcessor a <code>DbRowProcessor</code> instance, if it's
* <code>null</code> no processing will be performed on the fetched row
* @return <code>true</code> if a new row was retrieved; or
* <p><code>false</code> if there are no more rows .
* @exception DatabaseException when an error occurred during the fetch of
* the next row in the resultset
* @see #fetch(ResultSet)
* @see DbRowProcessor
* @since 1.0
*/
public boolean fetch(ResultSet resultSet, DbRowProcessor rowProcessor)
throws DatabaseException
{
if (null == resultSet) throw new IllegalArgumentException("resultSet can't be null.");
try
{
if (resultSet.next())
{
if (rowProcessor != null)
{
rowProcessor.processRowWrapper(resultSet);
}
return true;
}
}
catch (SQLException e)
{
throw new RowProcessorErrorException(e);
}
return false;
}
/**
* Fetches all the next rows of a resultset and processes it through a
* <code>DbRowProcessor</code>.
*
* @param resultSet a valid <code>ResultSet</code> instance
* @param rowProcessor a <code>DbRowProcessor</code> instance, if it's
* <code>null</code> no processing will be performed on the fetched rows
* @return <code>true</code> if rows were fetched; or
* <p><code>false</code> if the resultset contained no rows.
* @exception DatabaseException when an error occurred during the fetch of
* the next rows in the resultset
* @see DbRowProcessor
* @since 1.0
*/
public boolean fetchAll(ResultSet resultSet, DbRowProcessor rowProcessor)
throws DatabaseException
{
if (null == rowProcessor) throw new IllegalArgumentException("rowProcessor can't be null.");
boolean result = false;
while (fetch(resultSet, rowProcessor))
{
result = true;
if (rowProcessor != null &&
!rowProcessor.wasSuccessful())
{
break;
}
}
return result;
}
/**
* Obtains a <code>DbConnection</code> of this <code>DbQueryManager</code>'s
* <code>Datasource</code>. Functions exactly as the wrapped {@link
* Datasource#getConnection()} method.
* @see Datasource#getConnection()
* @since 1.0
* @exception DatabaseException see {@link Datasource#getConnection()}
* @return the requested <code>DbConnection</code>
*/
public DbConnection getConnection()
throws DatabaseException
{
return mDatasource.getConnection();
}
/**
* Retrieves the <code>Datasource</code> of this
* <code>DbQueryManager</code>.
*
* @return the requested <code>Datasource</code>
* @since 1.0
*/
public Datasource getDatasource()
{
return mDatasource;
}
/**
* Simply clones the instance with the default clone method. This creates
* a shallow copy of all fields and the clone will in fact just be another
* reference to the same underlying data. The independence of each cloned
* instance is consciously not respected since they rely on resources that
* can't be cloned.
* @since 1.0
* @return a clone of this instance
*/
public Object clone()
{
try
{
return super.clone();
}
catch (CloneNotSupportedException e)
{
///CLOVER:OFF
// this should never happen
Logger.getLogger("com.uwyn.rife.database").severe(ExceptionUtils.getExceptionStackTrace(e));
return null;
///CLOVER:ON
}
}
private void defensiveClose(InputStream stream)
{
if (null == stream)
{
return;
}
try
{
stream.close();
}
catch (IOException e)
{
// couldn't close stream since it probably already has been
// closed after an exception
// proceed without reporting an error message.
}
}
private void defensiveClose(Reader reader)
{
if (null == reader)
{
return;
}
try
{
reader.close();
}
catch (IOException e)
{
// couldn't close reader since it probably already has been
// closed after an exception
// proceed without reporting an error message.
}
}
private void defensiveClose(DbStatement statement)
{
if (null == statement)
{
return;
}
try
{
statement.close();
}
catch (DatabaseException e)
{
// couldn't close statement since it probably already has been
// closed after an exception
// proceed without reporting an error message.
}
}
}