package edu.washington.escience.myria.operator;
import java.io.IOException;
import com.google.common.collect.ImmutableMap;
import edu.washington.escience.myria.DbException;
import edu.washington.escience.myria.TupleWriter;
import edu.washington.escience.myria.io.DataSink;
import edu.washington.escience.myria.storage.TupleBatch;
/**
* DataOutput is a {@link RootOperator} that can be used to serialize data in a streaming fashion. It consumes
* {@link TupleBatch}es from its child and passes them to a {@link TupleWriter}.
*
*
*/
public final class TupleSink extends RootOperator {
/** Required for Java serialization. */
private static final long serialVersionUID = 1L;
/** The class that will serialize the tuple batches. */
private final TupleWriter tupleWriter;
private final DataSink dataSink;
/** Whether this object has finished. */
private boolean done = false;
private boolean includeColumnHeader = true;
public TupleSink(
final Operator child,
final TupleWriter tupleWriter,
final DataSink dataSink,
boolean includeColumnHeader) {
this(child, tupleWriter, dataSink);
this.includeColumnHeader = includeColumnHeader;
}
/**
* Instantiate a new DataOutput operator, which will stream its tuples to the specified {@link TupleWriter}.
*
* @param child the source of tuples to be streamed.
* @param writer the {@link TupleWriter} which will serialize the tuples.
* @param dataSink the {@link DataSink} for the tuple destination
*/
public TupleSink(final Operator child, final TupleWriter tupleWriter, final DataSink dataSink) {
super(child);
this.dataSink = dataSink;
this.tupleWriter = tupleWriter;
}
@Override
protected void childEOI() throws DbException {
/* Do nothing. */
}
@Override
protected void childEOS() throws DbException {
try {
tupleWriter.done();
} catch (IOException e) {
throw new DbException(e);
}
done = true;
}
@Override
protected void consumeTuples(final TupleBatch tuples) throws DbException {
try {
tupleWriter.writeTuples(tuples);
} catch (IOException e) {
throw new DbException(e);
}
}
@Override
protected void init(final ImmutableMap<String, Object> execEnvVars) throws DbException {
try {
tupleWriter.open(dataSink.getOutputStream());
if (includeColumnHeader) {
tupleWriter.writeColumnHeaders(getChild().getSchema().getColumnNames());
}
} catch (IOException e) {
throw new DbException(e);
}
}
@Override
protected void cleanup() throws IOException {
if (!done) {
tupleWriter.error();
}
}
}