// Copyright (c) 2001 SPY internetworking <dustin@spy.net>
package net.spy.db;
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.Collection;
import net.spy.util.SpyConfig;
/**
* Superclass for dynamic SQL calls.
*/
public abstract class DBCP extends DBSP {
private int argumentIndex=1;
/**
* Get a DBCP object with the given DBConfig.
*/
public DBCP(SpyConfig conf) throws SQLException {
super(conf);
}
/**
* Get a DBCP object with the given Connection.
*/
public DBCP(Connection conn) throws SQLException {
super(conn);
}
/**
* Execute a query for update only.
*/
public boolean execute() throws SQLException {
boolean rv=true;
prepare();
rv=getPreparedStatement().execute();
return(rv);
}
/**
* Optional parameters are not currently supported for DBCP objects.
* This method will always throw a SQLException when called.
*
* @param name name of the parameter
* @param type type of the parameter
* @throws SQLException Optional Parameters are not supported
*/
@Override
protected void setOptional(String name, int type) throws SQLException {
throw new SQLException("Optional Parameters Not Supported on DBCP");
}
/**
* Get the CallableStatement for fetching output args.
* TODO get the get* methods implemented
*
* @return The CallableStatement for getting the RC's from.
*/
public CallableStatement getCallableStatement() {
CallableStatement rc=(CallableStatement)getPreparedStatement();
return(rc);
}
/**
* Fill in the arguments (with types) for the given list of parameters.
*
* @param v the list of Argument objects we need to add, in order
*/
@Override
protected void applyArgs(Collection<Argument> v) throws SQLException {
PreparedStatement pst=getPreparedStatement();
// Get the statement
if (pst==null) {
if(getCacheTime()>0) {
throw new IllegalArgumentException("Not Implemented!!");
//pst=prepareStatement(query, getCacheTime());
} else {
pst=prepareCall(getQuery());
}
}
// Use this iterator for the now positional arguments
for(Argument arg : getArguments()) {
int i=argumentIndex;
Object o=arg.getValue();
// Get it as an int so we can switch it
int type=arg.getJavaType();
try {
if(getParameterType(arg.getName()) == Parameter.OUTPUT) {
getLogger().debug("OUT -> Setting column %s(%d) type %s",
arg, i, type);
CallableStatement cst=(CallableStatement)pst;
cst.registerOutParameter(i, type);
} else {
getLogger().debug("IN -> Setting column %s(%d) type %s",
arg, i, type);
switch(type) {
case Types.BIT:
pst.setBoolean(i, ((Boolean)o).booleanValue());
break;
case Types.DATE:
pst.setDate(i, (java.sql.Date)o);
break;
case Types.DOUBLE:
pst.setDouble(i, ((Double)o).doubleValue());
break;
case Types.FLOAT:
pst.setFloat(i, ((Float)o).floatValue());
break;
case Types.INTEGER:
pst.setInt(i, ((Integer)o).intValue());
break;
case Types.BIGINT:
pst.setLong(i, ((Long)o).longValue());
break;
case Types.NUMERIC:
case Types.DECIMAL:
BigDecimal bd=((BigDecimal)o).setScale(4,
BigDecimal.ROUND_HALF_UP);
pst.setBigDecimal(i, bd);
break;
case Types.SMALLINT:
case Types.TINYINT:
pst.setShort(i, (short)((Integer)o).intValue());
break;
case Types.NULL:
pst.setNull(i, ((DBNull)o).getType());
break;
case Types.OTHER:
pst.setObject(i, o);
break;
case Types.VARCHAR:
pst.setString(i, (String)o);
break;
case Types.TIME:
pst.setTime(i, (Time)o);
break;
case Types.TIMESTAMP:
pst.setTimestamp(i, (Timestamp)o);
break;
default:
throw new SQLException("Whoops, type "
+ TypeNames.getTypeName(type) + "(" + type + ")"
+ " seems to have been overlooked.");
}
} // end output_arg if statement
} catch(SQLException se) {
throw se;
} catch (Exception applyException) {
getLogger().warn("Exception while applying", applyException);
String msg="Problem setting " + arg
+ " in prepared statement for type "
+ TypeNames.getTypeName(type) + " "
+ o.toString() + " : " + applyException;
throw new SQLException (msg);
}
argumentIndex++;
}
}
/**
* Prepare the statement for execution.
*/
@Override
protected void prepare() throws SQLException {
// Make sure all the arguments are there.
checkArgs();
// Get ready to build our query.
StringBuilder querySb=new StringBuilder(256);
querySb.append("{call ");
querySb.append(getSPName());
querySb.append(" (");
int nargs=getArguments().size();
for(int i=0; i<nargs; i++) {
querySb.append("?,");
}
// Remove the last comma if we had params
if(nargs>0) {
querySb.deleteCharAt(querySb.length()-1);
}
// finish out
querySb.append(")}");
String query=querySb.toString().trim();
if (getLogger().isDebugEnabled()) {
getLogger().debug("Query: "+query);
}
PreparedStatement pst=getPreparedStatement();
// Get a prepared statement, varies whether it's cachable or not.
if (pst==null) {
if(getCacheTime()>0) {
throw new IllegalArgumentException("Not Implemented");
//pst=prepareCall(query, getCacheTime());
} else {
pst=prepareCall(query);
}
setPreparedStatement(pst);
}
// Fill in the arguments.
setQuery(query);
applyArgs(getArguments());
}
}