package jeql.command.io;
import java.io.PrintWriter;
import jeql.api.row.Row;
import jeql.api.row.RowIterator;
import jeql.api.row.RowSchema;
import jeql.api.table.Table;
import jeql.engine.EngineContext;
import jeql.util.ClassUtil;
import jeql.util.TypeUtil;
/**
* Writes out a table with specified delimiters.
*
* @author mdavis
*
*/
public class TableTextWriter
{
public static void writeTbl(Table t, boolean showHeader, int limit) {
TableTextWriter writer = new TableTextWriter();
writer.setShowHeader(showHeader);
writer.setLimit(limit);
writer.write(t);
}
public static void writeTbl(Table t) {
TableTextWriter writer = new TableTextWriter();
writer.write(t);
}
protected PrintWriter writer = null;
protected String tableStart = null;
protected String tableEnd = null;
protected String rowStart = null;
protected String rowEnd = null;
protected String rowSep = null;
protected String colStart = null;
protected String colEnd = null;
protected String colSep = " ";
protected boolean outputValueAsCode = false;
protected boolean showHeader = false;
protected int limit = -1;
protected RowSchema schema;
public TableTextWriter() {
}
public void setShowHeader(boolean showHeader)
{
this.showHeader = showHeader;
}
public void setCode(boolean isCode)
{
if (! isCode)
return;
rowStart = "( ";
rowEnd = " )";
rowSep = "";
colSep = ", ";
outputValueAsCode = true;
}
public void setColSep(String sep) {
this.colSep = sep;
}
public void setRowSep(String sep) {
this.rowSep = sep;
}
public void setLimit(int limit)
{
this.limit = limit;
}
public void write(Table t)
{
write(EngineContext.OUTPUT_WRITER, t);
}
public void write(PrintWriter printWriter, Table t) {
this.writer = printWriter;
RowIterator rs = t.getRows().iterator();
schema = rs.getSchema();
if (tableStart != null) writer.print(tableStart);
if (showHeader) {
writeHeader(t, schema);
}
int count = 0;
while (true) {
Row row = rs.next();
if (row == null)
break;
// enforce limit
if (limit >= 0 && count >= limit)
break;
// output row separator and EOL
if (count > 0) {
if (rowSep != null)
writer.print(rowSep);
writer.println();
}
count++;
writeRow(row);
// flush row, so it is seen as soon as possible
writer.flush();
}
if (tableEnd != null) writer.print(tableEnd);
// output final EOL
writer.println();
writer.flush();
}
protected void writeHeader(Table tbl, RowSchema rs) {
for (int i = 0; i < rs.size(); i++) {
if (i > 0)
writer.print(", ");
writer.print(tbl.getColumnName(i) + ":" + ClassUtil.classname(rs.getType(i)));
}
writer.println(" ");
}
protected void writeRow(Row row)
{
if (rowStart != null)
writer.print(rowStart);
for (int i = 0; i < row.size(); i++) {
if (i > 0 && colSep != null)
writer.print(colSep);
writeCol(row, i);
}
if (rowEnd != null)
writer.print(rowEnd);
}
protected void writeColStart(Row row, int i)
{
if (colStart != null)
writer.print(colStart);
}
protected void writeColEnd(Row row, int i)
{
if (colEnd != null)
writer.print(colEnd);
}
protected void writeCol(Row row, int i) {
writeColStart(row, i);
Object value = row.getValue(i);
if (outputValueAsCode)
writeValueAsCode(value);
else
writer.print(TypeUtil.toString(value));
writeColEnd(row, i);
}
private void writeValueAsCode(Object value) {
if (value instanceof String)
writer.print("\"" + TypeUtil.toString(value) + "\"");
else
writer.print(TypeUtil.toString(value));
}
}