java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/RecfileFormatter.java
author František Kučera <franta-hg@frantovo.cz>
Fri, 23 Sep 2022 18:05:50 +0200
branchv_0
changeset 254 c4b901ff0703
parent 250 aae5009bd0af
permissions -rw-r--r--
recfile formatter: write record count (as a comment at the end of the relation)
franta-hg@60
     1
/**
franta-hg@60
     2
 * SQL-DK
franta-hg@202
     3
 * Copyright © 2015 František Kučera (frantovo.cz)
franta-hg@60
     4
 *
franta-hg@60
     5
 * This program is free software: you can redistribute it and/or modify
franta-hg@60
     6
 * it under the terms of the GNU General Public License as published by
franta-hg@250
     7
 * the Free Software Foundation, version 3 of the License.
franta-hg@60
     8
 *
franta-hg@60
     9
 * This program is distributed in the hope that it will be useful,
franta-hg@60
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
franta-hg@60
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
franta-hg@60
    12
 * GNU General Public License for more details.
franta-hg@60
    13
 *
franta-hg@60
    14
 * You should have received a copy of the GNU General Public License
franta-hg@60
    15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
franta-hg@60
    16
 */
franta-hg@60
    17
package info.globalcode.sql.dk.formatting;
franta-hg@60
    18
franta-hg@202
    19
import info.globalcode.sql.dk.ColorfulPrintWriter;
franta-hg@206
    20
import info.globalcode.sql.dk.configuration.PropertyDeclaration;
franta-hg@206
    21
import static info.globalcode.sql.dk.formatting.CommonProperties.COLORFUL;
franta-hg@206
    22
import static info.globalcode.sql.dk.formatting.CommonProperties.COLORFUL_DESCRIPTION;
franta-hg@248
    23
import java.util.logging.Level;
franta-hg@248
    24
import java.util.logging.Logger;
franta-hg@60
    25
franta-hg@60
    26
/**
franta-hg@248
    27
 * Prints results in the recfile format. This format is both human- and machine- readable. Can be
franta-hg@248
    28
 * processed by the <a href="https://www.gnu.org/software/recutils/">GNU Recutils</a>
franta-hg@248
    29
 * or <a href="https://relational-pipes.globalcode.info/">Relational pipes</a>.
franta-hg@60
    30
 *
franta-hg@60
    31
 * @author Ing. František Kučera (frantovo.cz)
franta-hg@60
    32
 */
franta-hg@248
    33
@PropertyDeclaration(name = COLORFUL, defaultValue = "false", type = Boolean.class, description = COLORFUL_DESCRIPTION)
franta-hg@248
    34
public class RecfileFormatter extends AbstractFormatter {
franta-hg@60
    35
franta-hg@248
    36
	private static final Logger log = Logger.getLogger(RecfileFormatter.class.getName());
franta-hg@248
    37
	public static final String NAME = "recfile"; // bash-completion:formatter
franta-hg@202
    38
	private final ColorfulPrintWriter out;
franta-hg@202
    39
	private boolean firstResult = true;
franta-hg@60
    40
franta-hg@248
    41
	public RecfileFormatter(FormatterContext formatterContext) {
franta-hg@60
    42
		super(formatterContext);
franta-hg@202
    43
		out = new ColorfulPrintWriter(formatterContext.getOutputStream());
franta-hg@248
    44
		out.setColorful(formatterContext.getProperties().getBoolean(COLORFUL, false));
franta-hg@202
    45
	}
franta-hg@202
    46
franta-hg@202
    47
	@Override
franta-hg@202
    48
	public void writeStartResultSet(ColumnsHeader header) {
franta-hg@202
    49
		super.writeStartResultSet(header);
franta-hg@202
    50
		printResultSeparator();
franta-hg@248
    51
		out.print(ColorfulPrintWriter.TerminalColor.Red, "%rec: ");
franta-hg@248
    52
		printRecfileValue(getCurrentRelationName());
franta-hg@248
    53
		// TODO: declare attribute data types where jdbc→recfile mapping is possible
franta-hg@202
    54
	}
franta-hg@202
    55
franta-hg@202
    56
	@Override
franta-hg@202
    57
	public void writeStartRow() {
franta-hg@202
    58
		super.writeStartRow();
franta-hg@202
    59
		println();
franta-hg@60
    60
	}
franta-hg@60
    61
franta-hg@60
    62
	@Override
franta-hg@60
    63
	public void writeColumnValue(Object value) {
franta-hg@60
    64
		super.writeColumnValue(value);
franta-hg@202
    65
		String columnName = getCurrentColumnsHeader().getColumnDescriptors().get(getCurrentColumnsCount() - 1).getLabel();
franta-hg@202
    66
		out.print(ColorfulPrintWriter.TerminalColor.Green, columnName + ": ");
franta-hg@248
    67
		printRecfileValue(value);
franta-hg@218
    68
	}
franta-hg@218
    69
franta-hg@60
    70
	@Override
franta-hg@254
    71
	public void writeEndResultSet() {
franta-hg@254
    72
		super.writeEndResultSet();
franta-hg@254
    73
		out.println();
franta-hg@254
    74
		out.print("# Record count: ");
franta-hg@254
    75
		out.println(getCurrentRowCount());
franta-hg@254
    76
		out.flush();
franta-hg@254
    77
	}
franta-hg@254
    78
franta-hg@254
    79
	@Override
franta-hg@142
    80
	public void writeUpdatesResult(int updatedRowsCount) {
franta-hg@142
    81
		super.writeUpdatesResult(updatedRowsCount);
franta-hg@202
    82
		printResultSeparator();
franta-hg@248
    83
		log.log(Level.INFO, "Updated records: {0}", updatedRowsCount);
franta-hg@202
    84
	}
franta-hg@202
    85
franta-hg@248
    86
	@Override
franta-hg@248
    87
	public void writeEndBatch() {
franta-hg@248
    88
		super.writeEndBatch();
franta-hg@248
    89
		println();
franta-hg@60
    90
	}
franta-hg@202
    91
franta-hg@202
    92
	private void println() {
franta-hg@202
    93
		out.println();
franta-hg@248
    94
		out.flush();
franta-hg@202
    95
	}
franta-hg@202
    96
franta-hg@248
    97
	private void printRecfileValue(Object value) {
franta-hg@248
    98
		if (value == null) {
franta-hg@248
    99
			// TODO: null values in recfiles?
franta-hg@248
   100
		} else {
franta-hg@248
   101
			for (char ch : value.toString().toCharArray()) {
franta-hg@248
   102
				out.print(ch);
franta-hg@248
   103
				if (ch == '\n') {
franta-hg@248
   104
					out.print(ColorfulPrintWriter.TerminalColor.Magenta, "+ ");
franta-hg@248
   105
				}
franta-hg@248
   106
			}
franta-hg@202
   107
		}
franta-hg@248
   108
		println();
franta-hg@202
   109
	}
franta-hg@202
   110
franta-hg@202
   111
	private void printResultSeparator() {
franta-hg@202
   112
		if (firstResult) {
franta-hg@202
   113
			firstResult = false;
franta-hg@202
   114
		} else {
franta-hg@202
   115
			println();
franta-hg@202
   116
		}
franta-hg@202
   117
	}
franta-hg@60
   118
}