java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/TabularPrefetchingFormatter.java
author František Kučera <franta-hg@frantovo.cz>
Thu, 24 Oct 2019 21:43:08 +0200
branchv_0
changeset 250 aae5009bd0af
parent 238 4a1864c3e867
permissions -rw-r--r--
fix license version: GNU GPLv3
     1 /**
     2  * SQL-DK
     3  * Copyright © 2013 František Kučera (frantovo.cz)
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, version 3 of the License.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License
    15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
    16  */
    17 package info.globalcode.sql.dk.formatting;
    18 
    19 import java.util.ArrayList;
    20 import java.util.List;
    21 
    22 /**
    23  * <p>
    24  * Prefetches whole result set and computes column widths. Whole table is flushed at once in
    25  * {@linkplain #writeEndResultSet()}.
    26  * </p>
    27  *
    28  * <p>
    29  * Long values will not overflow the cells, but whole result set must be loaded into the memory.
    30  * </p>
    31  *
    32  * @author Ing. František Kučera (frantovo.cz)
    33  */
    34 public class TabularPrefetchingFormatter extends TabularFormatter {
    35 
    36 	public static final String NAME = "tabular-prefetching"; // bash-completion:formatter
    37 	private ColumnsHeader currentHeader;
    38 	private List<Object[]> currentResultSet;
    39 	private Object[] currentRow;
    40 	private int currentColumnsCount;
    41 	private boolean prefetchDone = false;
    42 
    43 	public TabularPrefetchingFormatter(FormatterContext formatterContext) {
    44 		super(formatterContext);
    45 	}
    46 
    47 	@Override
    48 	protected int getCurrentColumnsCount() {
    49 		if (prefetchDone) {
    50 			return super.getCurrentColumnsCount();
    51 		} else {
    52 			return currentColumnsCount;
    53 		}
    54 	}
    55 
    56 	@Override
    57 	public void writeStartResultSet(ColumnsHeader header) {
    58 		currentResultSet = new ArrayList<>();
    59 		currentHeader = header;
    60 		initColumnWidths(header.getColumnCount());
    61 	}
    62 
    63 	@Override
    64 	public void writeStartRow() {
    65 		currentRow = new Object[currentHeader.getColumnCount()];
    66 		currentResultSet.add(currentRow);
    67 		currentColumnsCount = 0;
    68 	}
    69 
    70 	@Override
    71 	public void writeColumnValue(Object value) {
    72 		currentRow[currentColumnsCount] = value;
    73 		currentColumnsCount++;
    74 		String textRepresentation = toString(value);
    75 		/** TODO: count only printable characters (currently not an issue) */
    76 		updateColumnWidth(currentColumnsCount, textRepresentation.length());
    77 	}
    78 
    79 	@Override
    80 	public void writeEndRow() {
    81 		// do nothing
    82 	}
    83 
    84 	@Override
    85 	public void writeEndResultSet() {
    86 		prefetchDone = true;
    87 
    88 		postprocessPrefetchedResultSet(currentHeader, currentResultSet);
    89 
    90 		super.writeStartResultSet(currentHeader);
    91 
    92 		for (Object[] row : currentResultSet) {
    93 			super.writeStartRow();
    94 			for (Object cell : row) {
    95 				super.writeColumnValue(cell);
    96 			}
    97 			super.writeEndRow();
    98 		}
    99 
   100 		currentColumnsCount = 0;
   101 		currentHeader = null;
   102 		currentRow = null;
   103 		currentResultSet = null;
   104 		super.writeEndResultSet();
   105 		prefetchDone = false;
   106 	}
   107 
   108 	/**
   109 	 * Optional post-processing – override in sub-classes if needed.
   110 	 * Don't forget to {@linkplain #updateColumnWidth(int, int)}
   111 	 *
   112 	 * @param currentHeader
   113 	 * @param currentResultSet
   114 	 */
   115 	protected void postprocessPrefetchedResultSet(ColumnsHeader currentHeader, List<Object[]> currentResultSet) {
   116 	}
   117 
   118 }