franta-hg@88: /** franta-hg@88: * SQL-DK franta-hg@88: * Copyright © 2013 František Kučera (frantovo.cz) franta-hg@88: * franta-hg@88: * This program is free software: you can redistribute it and/or modify franta-hg@88: * it under the terms of the GNU General Public License as published by franta-hg@88: * the Free Software Foundation, either version 3 of the License, or franta-hg@88: * (at your option) any later version. franta-hg@88: * franta-hg@88: * This program is distributed in the hope that it will be useful, franta-hg@88: * but WITHOUT ANY WARRANTY; without even the implied warranty of franta-hg@88: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the franta-hg@88: * GNU General Public License for more details. franta-hg@88: * franta-hg@88: * You should have received a copy of the GNU General Public License franta-hg@88: * along with this program. If not, see . franta-hg@88: */ franta-hg@88: package info.globalcode.sql.dk.formatting; franta-hg@88: franta-hg@88: import java.util.ArrayList; franta-hg@88: import java.util.List; franta-hg@88: franta-hg@88: /** franta-hg@155: *

franta-hg@88: * Prefetches whole result set and computes column widths. Whole table is flushed at once in franta-hg@88: * {@linkplain #writeEndResultSet()}. franta-hg@155: *

franta-hg@88: * franta-hg@155: *

franta-hg@155: * Long values will not overflow the cells, but whole result set must be loaded into the memory. franta-hg@155: *

franta-hg@88: * franta-hg@88: * @author Ing. František Kučera (frantovo.cz) franta-hg@88: */ franta-hg@88: public class TabularPrefetchingFormatter extends TabularFormatter { franta-hg@88: franta-hg@88: public static final String NAME = "tabular-prefetching"; // bash-completion:formatter franta-hg@88: private ColumnsHeader currentHeader; franta-hg@88: private List currentResultSet; franta-hg@88: private Object[] currentRow; franta-hg@88: private int currentColumnsCount; franta-hg@88: private boolean prefetchDone = false; franta-hg@88: franta-hg@88: public TabularPrefetchingFormatter(FormatterContext formatterContext) { franta-hg@88: super(formatterContext); franta-hg@88: } franta-hg@88: franta-hg@88: @Override franta-hg@88: protected int getCurrentColumnsCount() { franta-hg@88: if (prefetchDone) { franta-hg@88: return super.getCurrentColumnsCount(); franta-hg@88: } else { franta-hg@88: return currentColumnsCount; franta-hg@88: } franta-hg@88: } franta-hg@88: franta-hg@88: @Override franta-hg@142: public void writeStartResultSet(ColumnsHeader header) { franta-hg@88: currentResultSet = new ArrayList<>(); franta-hg@88: currentHeader = header; franta-hg@88: initColumnWidths(header.getColumnCount()); franta-hg@88: } franta-hg@88: franta-hg@88: @Override franta-hg@88: public void writeStartRow() { franta-hg@88: currentRow = new Object[currentHeader.getColumnCount()]; franta-hg@88: currentResultSet.add(currentRow); franta-hg@88: currentColumnsCount = 0; franta-hg@88: } franta-hg@88: franta-hg@88: @Override franta-hg@88: public void writeColumnValue(Object value) { franta-hg@88: currentRow[currentColumnsCount] = value; franta-hg@88: currentColumnsCount++; franta-hg@88: String textRepresentation = toString(value); franta-hg@88: /** TODO: count only printable characters (currently not an issue) */ franta-hg@88: updateColumnWidth(currentColumnsCount, textRepresentation.length()); franta-hg@88: } franta-hg@88: franta-hg@88: @Override franta-hg@88: public void writeEndRow() { franta-hg@88: // do nothing franta-hg@88: } franta-hg@88: franta-hg@88: @Override franta-hg@88: public void writeEndResultSet() { franta-hg@88: prefetchDone = true; franta-hg@88: franta-hg@224: postprocessPrefetchedResultSet(currentHeader, currentResultSet); franta-hg@224: franta-hg@142: super.writeStartResultSet(currentHeader); franta-hg@88: franta-hg@88: for (Object[] row : currentResultSet) { franta-hg@88: super.writeStartRow(); franta-hg@88: for (Object cell : row) { franta-hg@88: super.writeColumnValue(cell); franta-hg@88: } franta-hg@88: super.writeEndRow(); franta-hg@88: } franta-hg@88: franta-hg@88: currentColumnsCount = 0; franta-hg@88: currentHeader = null; franta-hg@88: currentRow = null; franta-hg@88: currentResultSet = null; franta-hg@88: super.writeEndResultSet(); franta-hg@88: prefetchDone = false; franta-hg@88: } franta-hg@224: franta-hg@224: /** franta-hg@224: * Optional post-processing – override in sub-classes if needed. franta-hg@224: * Don't forget to {@linkplain #updateColumnWidth(int, int)} franta-hg@224: * franta-hg@224: * @param currentHeader franta-hg@224: * @param currentResultSet franta-hg@224: */ franta-hg@224: protected void postprocessPrefetchedResultSet(ColumnsHeader currentHeader, List currentResultSet) { franta-hg@224: } franta-hg@224: franta-hg@88: }