package org.oddjob.sql;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.oddjob.arooa.ArooaSession;
import org.oddjob.arooa.convert.ArooaConversionException;
import org.oddjob.arooa.deploy.annotations.ArooaHidden;
import org.oddjob.arooa.life.ArooaSessionAware;
import org.oddjob.beanbus.AbstractFilter;
import org.oddjob.beanbus.BusConductor;
import org.oddjob.beanbus.BusCrashException;
import org.oddjob.beanbus.BusEvent;
import org.oddjob.beanbus.TrackingBusListener;
import org.oddjob.beanbus.destinations.BeanSheet;
import org.oddjob.io.StdoutType;
import org.oddjob.util.StreamPrinter;
/**
* @oddjob.description Writes SQL results to an output stream.
*
* @oddjob.example
*
* A result sheet for multiple statements.
*
* {@oddjob.xml.resource org/oddjob/sql/SQLResultsSheetExample.xml}
*
* This writes the following to the console:
*
* <code><pre>
* [0 rows affected, 16 ms.]
*
* [1 rows affected, 0 ms.]
*
* [1 rows affected, 0 ms.]
*
* TYPE VARIETY COLOUR SIZE
* ------ ------- ------------- -----
* Apple Cox Red and Green 7.6
* Orange Jaffa Orange 9.245
*
* [2 rows, 212 ms.]
*
* [0 rows affected, 0 ms.]
*
* </pre></code>
*
* @author rob
*
*/
public class SQLResultsSheet extends AbstractFilter<Object, Object>
implements ArooaSessionAware {
private static final Logger logger = Logger.getLogger(SQLResultsSheet.class);
/**
* @oddjob.property
* @oddjob.description The output stream to write results to.
* @oddjob.required No. Defaults to stdout.
*/
private OutputStream output;
/**
* @oddjob.property
* @oddjob.description Don't display headings.
* @oddjob.required No. Defaults to showing headings.
*/
private boolean dataOnly;
/** The session. */
private ArooaSession session;
/** Used to display elapsed time. */
private long elapsedTime = System.currentTimeMillis();
private final List<Object> beans = new ArrayList<Object>();
private final TrackingBusListener busListener =
new TrackingBusListener() {
@Override
public void busStarting(BusEvent event) throws BusCrashException {
if (output == null) {
try {
output = new StdoutType().toValue();
} catch (ArooaConversionException e) {
throw new BusCrashException(e);
}
}
}
@Override
public void tripBeginning(BusEvent event) {
elapsedTime = System.currentTimeMillis();
}
@Override
public void tripEnding(BusEvent event) {
writeBeans(beans);
beans.clear();
if (!dataOnly) {
new StreamPrinter(output).println();
}
}
@Override
public void busTerminated(BusEvent event) {
try {
if (output != null) {
output.close();
}
}
catch (IOException ioe) {
logger.error("Failed to close output.", ioe);
}
}
};
@Override
@ArooaHidden
public void setArooaSession(ArooaSession session) {
this.session = session;
}
@Override
protected Object filter(Object from) {
beans.add(from);
return from;
}
public void writeBeans(List<Object> beans) {
elapsedTime = System.currentTimeMillis() - elapsedTime;
if (beans.size() > 0 &&
beans.get(0) instanceof UpdateCount) {
if (dataOnly) {
logger.debug("Ignoring update counts for data only.");
}
else {
UpdateCount updateCount = (UpdateCount) beans.get(0);
new StreamPrinter(output).println("[" + updateCount.getCount() + " rows affected, " +
elapsedTime + " ms.]");
}
}
else {
BeanSheet sheet = new BeanSheet();
sheet.setArooaSession(session);
sheet.setNoHeaders(dataOnly);
sheet.setOutput(output);
sheet.writeBeans(beans);
if (!dataOnly) {
new StreamPrinter(output).println();
new StreamPrinter(output).println("[" + beans.size() + " rows, " +
elapsedTime + " ms.]");
}
}
}
public OutputStream getOutput() {
return output;
}
public void setOutput(OutputStream output) {
this.output = output;
}
public boolean isDataOnly() {
return dataOnly;
}
public void setDataOnly(boolean dataOnly) {
this.dataOnly = dataOnly;
}
@ArooaHidden
@Inject
public void setBusConductor(BusConductor busConductor) {
this.busListener.setBusConductor(busConductor);
}
}