java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/RecfileFormatter.java
author František Kučera <franta-hg@frantovo.cz>
Sun, 04 Feb 2024 16:10:37 +0100
branchv_0
changeset 255 099bb96f8d8d
parent 254 c4b901ff0703
permissions -rw-r--r--
tabular formatter: new option 'separateBy' to print horizontal separator on each change of given column
     1 /**
     2  * SQL-DK
     3  * Copyright © 2015 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 info.globalcode.sql.dk.ColorfulPrintWriter;
    20 import info.globalcode.sql.dk.configuration.PropertyDeclaration;
    21 import static info.globalcode.sql.dk.formatting.CommonProperties.COLORFUL;
    22 import static info.globalcode.sql.dk.formatting.CommonProperties.COLORFUL_DESCRIPTION;
    23 import java.util.logging.Level;
    24 import java.util.logging.Logger;
    25 
    26 /**
    27  * Prints results in the recfile format. This format is both human- and machine- readable. Can be
    28  * processed by the <a href="https://www.gnu.org/software/recutils/">GNU Recutils</a>
    29  * or <a href="https://relational-pipes.globalcode.info/">Relational pipes</a>.
    30  *
    31  * @author Ing. František Kučera (frantovo.cz)
    32  */
    33 @PropertyDeclaration(name = COLORFUL, defaultValue = "false", type = Boolean.class, description = COLORFUL_DESCRIPTION)
    34 public class RecfileFormatter extends AbstractFormatter {
    35 
    36 	private static final Logger log = Logger.getLogger(RecfileFormatter.class.getName());
    37 	public static final String NAME = "recfile"; // bash-completion:formatter
    38 	private final ColorfulPrintWriter out;
    39 	private boolean firstResult = true;
    40 
    41 	public RecfileFormatter(FormatterContext formatterContext) {
    42 		super(formatterContext);
    43 		out = new ColorfulPrintWriter(formatterContext.getOutputStream());
    44 		out.setColorful(formatterContext.getProperties().getBoolean(COLORFUL, false));
    45 	}
    46 
    47 	@Override
    48 	public void writeStartResultSet(ColumnsHeader header) {
    49 		super.writeStartResultSet(header);
    50 		printResultSeparator();
    51 		out.print(ColorfulPrintWriter.TerminalColor.Red, "%rec: ");
    52 		printRecfileValue(getCurrentRelationName());
    53 		// TODO: declare attribute data types where jdbc→recfile mapping is possible
    54 	}
    55 
    56 	@Override
    57 	public void writeStartRow() {
    58 		super.writeStartRow();
    59 		println();
    60 	}
    61 
    62 	@Override
    63 	public void writeColumnValue(Object value) {
    64 		super.writeColumnValue(value);
    65 		String columnName = getCurrentColumnsHeader().getColumnDescriptors().get(getCurrentColumnsCount() - 1).getLabel();
    66 		out.print(ColorfulPrintWriter.TerminalColor.Green, columnName + ": ");
    67 		printRecfileValue(value);
    68 	}
    69 
    70 	@Override
    71 	public void writeEndResultSet() {
    72 		super.writeEndResultSet();
    73 		out.println();
    74 		out.print("# Record count: ");
    75 		out.println(getCurrentRowCount());
    76 		out.flush();
    77 	}
    78 
    79 	@Override
    80 	public void writeUpdatesResult(int updatedRowsCount) {
    81 		super.writeUpdatesResult(updatedRowsCount);
    82 		printResultSeparator();
    83 		log.log(Level.INFO, "Updated records: {0}", updatedRowsCount);
    84 	}
    85 
    86 	@Override
    87 	public void writeEndBatch() {
    88 		super.writeEndBatch();
    89 		println();
    90 	}
    91 
    92 	private void println() {
    93 		out.println();
    94 		out.flush();
    95 	}
    96 
    97 	private void printRecfileValue(Object value) {
    98 		if (value == null) {
    99 			// TODO: null values in recfiles?
   100 		} else {
   101 			for (char ch : value.toString().toCharArray()) {
   102 				out.print(ch);
   103 				if (ch == '\n') {
   104 					out.print(ColorfulPrintWriter.TerminalColor.Magenta, "+ ");
   105 				}
   106 			}
   107 		}
   108 		println();
   109 	}
   110 
   111 	private void printResultSeparator() {
   112 		if (firstResult) {
   113 			firstResult = false;
   114 		} else {
   115 			println();
   116 		}
   117 	}
   118 }