/*
* Copyright(c) 2005 Center for E-Commerce Infrastructure Development, The
* University of Hong Kong (HKU). All Rights Reserved.
*
* This software is licensed under the GNU GENERAL PUBLIC LICENSE Version 2.0 [1]
*
* [1] http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*/
package hk.hku.cecid.piazza.commons.dao.ds;
import hk.hku.cecid.piazza.commons.dao.DAOException;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
/**
* DataSourceQuery is a data source DAO process which handles a SQL query
* process.
*
* @author Hugo Y. K. Lam
*
*/
class DataSourceQuery extends DataSourceProcess {
private String sql;
private Object[] params;
private boolean isRawResult;
/**
* Creates a new instance of DataSourceQuery.
*
* @param dao the DAO to which this process correspond.
* @param transaction the transaction for this process.
* @param sql the SQL query statement.
* @param params the parameter values used by the specified SQL statement.
* The number, format, and sequence of the parameter values
* should match the statement. null if there is no parameter for
* the statement.
*/
DataSourceQuery(DataSourceDAO dao, DataSourceTransaction transaction, String sql, Object[] params) {
super(dao, transaction);
this.sql = sql;
this.params = params;
}
/**
* Executes the query and stores the result as a list of DataSourceDVO or
* raw data list.
*
* @throws DAOException if unable to execute the query.
* @see hk.hku.cecid.piazza.commons.dao.ds.DataSourceProcess#doTransaction(DataSourceTransaction)
*/
protected void doTransaction(DataSourceTransaction tx) throws DAOException {
ResultSet rs = null;
PreparedStatement pStmt = null;
try {
if (sql == null) {
throw new DAOException("SQL in query cannot be NULL");
}
pStmt = tx.getConnection().prepareStatement(sql);
int noOfParas = getParameterCount(pStmt, sql);
// check the input parameters for the SQL statement
if (noOfParas > 0) {
if (params == null || params.length != noOfParas) {
throw new DAOException(
"Number of parameters specified do not match in the SQL");
}
else {
for (int i = 0; i < noOfParas; i++) {
setParameter(pStmt, i + 1, params[i]);
}
}
}
// execute the query
rs = pStmt.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
String[] columnNames = new String[numberOfColumns];
for (int i = 0; i < columnNames.length; i++) {
columnNames[i] = rsmd.getColumnName(i + 1);
}
// pack the data retrieved into a List of DataSourceDVO
List result = new ArrayList();
while (rs.next()) {
if (isRawResult) {
List data = new ArrayList();
int cc = rsmd.getColumnCount();
for (int i=1; i<=cc; i++) {
Object value = rs.getObject(i);
data.add(value);
}
result.add(data);
}
else {
Hashtable values = new Hashtable();
for (int i = 0; i < columnNames.length; i++) {
Object value = rs.getObject(columnNames[i]);
String columnCodeName = getDAO().getColumnCodeName(columnNames[i]);
if (value != null && columnCodeName!=null) {
if (value instanceof java.sql.Blob) {
java.sql.Blob blob = (java.sql.Blob)value;
byte[] b = new byte[8196];
int j = 0;
InputStream is = blob.getBinaryStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (( j = is.read(b)) > 0) {
baos.write(b, 0, j);
}
values.put(columnCodeName, baos.toByteArray());
} else {
values.put(columnCodeName, value);
}
}
}
DataSourceDVO data = (DataSourceDVO) getDAO().createDVO();
data.setData(values);
result.add(data);
}
}
setResult(result);
}
catch (Exception e) {
throw new DAOException("Error in executing query: " + sql, e);
}
finally {
if (rs!=null) {
try {
rs.close();
}
catch (Exception ex) {
throw new DAOException("Error in closing result set: ", ex);
}
}
if (pStmt!=null) {
try {
pStmt.close();
}
catch (Exception ex) {
throw new DAOException("Error in closing prepared statement: ", ex);
}
}
}
}
/**
* Checks if the result data is in raw format.
*
* @return true if the result data is in raw format.
* @see #setRawResult(boolean)
*/
public boolean isRawResult() {
return isRawResult;
}
/**
* Sets whether the result data should be in raw format. If true, the result
* data will be a list of DataSourceDVO. Otherwise, it will be a list of list
* which contains the data values in order with the query.
*
* @param isRawResult true if the result data should be in raw format.
*/
public void setRawResult(boolean isRawResult) {
this.isRawResult = isRawResult;
}
}