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