# HG changeset patch # User František Kučera # Date 1556646557 -7200 # Node ID 7f81cfa150d0633023ed6779659091cdca7fc8a5 # Parent 3380ae5275bea7d93e44c00366a71738cf208466 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 diff -r 3380ae5275be -r 7f81cfa150d0 java/sql-dk/src/main/java/info/globalcode/sql/dk/configuration/Configuration.java --- a/java/sql-dk/src/main/java/info/globalcode/sql/dk/configuration/Configuration.java Mon Apr 29 01:27:26 2019 +0200 +++ b/java/sql-dk/src/main/java/info/globalcode/sql/dk/configuration/Configuration.java Tue Apr 30 19:49:17 2019 +0200 @@ -20,8 +20,8 @@ import static info.globalcode.sql.dk.Xmlns.CONFIGURATION; import static info.globalcode.sql.dk.Functions.findByName; import info.globalcode.sql.dk.formatting.BarChartFormatter; +import info.globalcode.sql.dk.formatting.RecfileFormatter; import info.globalcode.sql.dk.formatting.SilentFormatter; -import info.globalcode.sql.dk.formatting.SingleRecordFormatter; import info.globalcode.sql.dk.formatting.SingleValueFormatter; import info.globalcode.sql.dk.formatting.TabularFormatter; import info.globalcode.sql.dk.formatting.TabularPrefetchingFormatter; @@ -66,7 +66,7 @@ Collection l = new ArrayList<>(); l.add(new FormatterDefinition(SilentFormatter.NAME, SilentFormatter.class.getName())); l.add(new FormatterDefinition(SingleValueFormatter.NAME, SingleValueFormatter.class.getName())); - l.add(new FormatterDefinition(SingleRecordFormatter.NAME, SingleRecordFormatter.class.getName())); + l.add(new FormatterDefinition(RecfileFormatter.NAME, RecfileFormatter.class.getName())); l.add(new FormatterDefinition(XmlFormatter.NAME, XmlFormatter.class.getName())); l.add(new FormatterDefinition(XhtmlFormatter.NAME, XhtmlFormatter.class.getName())); l.add(new FormatterDefinition(TabularFormatter.NAME, TabularFormatter.class.getName())); diff -r 3380ae5275be -r 7f81cfa150d0 java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/AbstractFormatter.java --- a/java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/AbstractFormatter.java Mon Apr 29 01:27:26 2019 +0200 +++ b/java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/AbstractFormatter.java Tue Apr 30 19:49:17 2019 +0200 @@ -41,12 +41,21 @@ private String currentQuery; private int currentColumnsCount; private int currentRowCount; + private int resultSetCount; public AbstractFormatter(FormatterContext formatterContext) { this.formatterContext = formatterContext; state.push(State.ROOT); } + protected String getCurrentRelationName() { + if (getFormatterContext().getRelationNames() == null || getFormatterContext().getRelationNames().size() < resultSetCount) { + return "r" + resultSetCount; + } else { + return getFormatterContext().getRelationNames().get(resultSetCount - 1); + } + } + /* * root * .batch @@ -126,6 +135,7 @@ @Override public void writeStartBatch() { pushState(State.BATCH, EnumSet.of(State.ROOT)); + resultSetCount = 0; } @Override @@ -156,6 +166,7 @@ @Override public void writeStartResultSet(ColumnsHeader header) { pushState(State.RESULT_SET, EnumSet.of(State.STATEMENT)); + resultSetCount++; currentRowCount = 0; currentColumnsHeader = header; } diff -r 3380ae5275be -r 7f81cfa150d0 java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/RecfileFormatter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/RecfileFormatter.java Tue Apr 30 19:49:17 2019 +0200 @@ -0,0 +1,110 @@ +/** + * SQL-DK + * Copyright © 2015 František Kučera (frantovo.cz) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package info.globalcode.sql.dk.formatting; + +import info.globalcode.sql.dk.ColorfulPrintWriter; +import info.globalcode.sql.dk.configuration.PropertyDeclaration; +import static info.globalcode.sql.dk.formatting.CommonProperties.COLORFUL; +import static info.globalcode.sql.dk.formatting.CommonProperties.COLORFUL_DESCRIPTION; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Prints results in the recfile format. This format is both human- and machine- readable. Can be + * processed by the GNU Recutils + * or Relational pipes. + * + * @author Ing. František Kučera (frantovo.cz) + */ +@PropertyDeclaration(name = COLORFUL, defaultValue = "false", type = Boolean.class, description = COLORFUL_DESCRIPTION) +public class RecfileFormatter extends AbstractFormatter { + + private static final Logger log = Logger.getLogger(RecfileFormatter.class.getName()); + public static final String NAME = "recfile"; // bash-completion:formatter + private final ColorfulPrintWriter out; + private boolean firstResult = true; + + public RecfileFormatter(FormatterContext formatterContext) { + super(formatterContext); + out = new ColorfulPrintWriter(formatterContext.getOutputStream()); + out.setColorful(formatterContext.getProperties().getBoolean(COLORFUL, false)); + } + + @Override + public void writeStartResultSet(ColumnsHeader header) { + super.writeStartResultSet(header); + printResultSeparator(); + out.print(ColorfulPrintWriter.TerminalColor.Red, "%rec: "); + printRecfileValue(getCurrentRelationName()); + // TODO: declare attribute data types where jdbc→recfile mapping is possible + } + + @Override + public void writeStartRow() { + super.writeStartRow(); + println(); + } + + @Override + public void writeColumnValue(Object value) { + super.writeColumnValue(value); + String columnName = getCurrentColumnsHeader().getColumnDescriptors().get(getCurrentColumnsCount() - 1).getLabel(); + out.print(ColorfulPrintWriter.TerminalColor.Green, columnName + ": "); + printRecfileValue(value); + } + + @Override + public void writeUpdatesResult(int updatedRowsCount) { + super.writeUpdatesResult(updatedRowsCount); + printResultSeparator(); + log.log(Level.INFO, "Updated records: {0}", updatedRowsCount); + } + + @Override + public void writeEndBatch() { + super.writeEndBatch(); + println(); + } + + private void println() { + out.println(); + out.flush(); + } + + private void printRecfileValue(Object value) { + if (value == null) { + // TODO: null values in recfiles? + } else { + for (char ch : value.toString().toCharArray()) { + out.print(ch); + if (ch == '\n') { + out.print(ColorfulPrintWriter.TerminalColor.Magenta, "+ "); + } + } + } + println(); + } + + private void printResultSeparator() { + if (firstResult) { + firstResult = false; + } else { + println(); + } + } +} diff -r 3380ae5275be -r 7f81cfa150d0 java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/SingleRecordFormatter.java --- a/java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/SingleRecordFormatter.java Mon Apr 29 01:27:26 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ -/** - * SQL-DK - * Copyright © 2015 František Kučera (frantovo.cz) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package info.globalcode.sql.dk.formatting; - -import info.globalcode.sql.dk.ColorfulPrintWriter; -import info.globalcode.sql.dk.Functions; -import info.globalcode.sql.dk.configuration.PropertyDeclaration; -import static info.globalcode.sql.dk.formatting.CommonProperties.COLORFUL; -import static info.globalcode.sql.dk.formatting.CommonProperties.COLORFUL_DESCRIPTION; - -/** - * Formatter intended for printing one record (or few records) with many columns. - * Prints each colum name and its value on separate line. - * - * @author Ing. František Kučera (frantovo.cz) - */ -@PropertyDeclaration(name = COLORFUL, defaultValue = "true", type = Boolean.class, description = COLORFUL_DESCRIPTION) -public class SingleRecordFormatter extends AbstractFormatter { - - public static final String NAME = "record"; // bash-completion:formatter - private final ColorfulPrintWriter out; - private boolean firstResult = true; - - public SingleRecordFormatter(FormatterContext formatterContext) { - super(formatterContext); - out = new ColorfulPrintWriter(formatterContext.getOutputStream()); - out.setColorful(formatterContext.getProperties().getBoolean(COLORFUL, true)); - } - - @Override - public void writeStartResultSet(ColumnsHeader header) { - super.writeStartResultSet(header); - printResultSeparator(); - } - - @Override - public void writeStartRow() { - super.writeStartRow(); - printRecordSeparator(); - out.print(ColorfulPrintWriter.TerminalColor.Red, "Record: "); - out.print(getCurrentRowCount()); - println(); - } - - @Override - public void writeColumnValue(Object value) { - super.writeColumnValue(value); - String columnName = getCurrentColumnsHeader().getColumnDescriptors().get(getCurrentColumnsCount() - 1).getLabel(); - out.print(ColorfulPrintWriter.TerminalColor.Green, columnName + ": "); - Functions.printValueWithWhitespaceReplaced(out, toString(value), null, ColorfulPrintWriter.TerminalColor.Red); - println(); - } - - private static String toString(Object value) { - return String.valueOf(value); - } - - @Override - public void writeUpdatesResult(int updatedRowsCount) { - super.writeUpdatesResult(updatedRowsCount); - printResultSeparator(); - out.print(ColorfulPrintWriter.TerminalColor.Red, "Updated records: "); - out.println(updatedRowsCount); - printBellAndFlush(); - } - - private void printBellAndFlush() { - out.bell(); - out.flush(); - } - - private void println() { - out.println(); - printBellAndFlush(); - } - - private void printRecordSeparator() { - if (getCurrentRowCount() > 1) { - println(); - } - } - - private void printResultSeparator() { - if (firstResult) { - firstResult = false; - } else { - println(); - } - } -} diff -r 3380ae5275be -r 7f81cfa150d0 java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/XmlFormatter.java --- a/java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/XmlFormatter.java Mon Apr 29 01:27:26 2019 +0200 +++ b/java/sql-dk/src/main/java/info/globalcode/sql/dk/formatting/XmlFormatter.java Tue Apr 30 19:49:17 2019 +0200 @@ -85,7 +85,7 @@ private String currentDatabaseName; private int statementCounter; - private int resultSetCounter; + public XmlFormatter(FormatterContext formatterContext) { super(formatterContext); @@ -109,7 +109,6 @@ attributes.put(new QName(null, XML_NS_PREFIX_SQLDK, "xmlns"), Xmlns.SQLDK); printStartElement(qname("relpipe"), attributes); statementCounter = 0; - resultSetCounter = 0; } @@ -183,18 +182,9 @@ } - private String getCurrentRelationName() { - if (getFormatterContext().getRelationNames() == null || getFormatterContext().getRelationNames().size() < resultSetCounter) { - return "r" + resultSetCounter; - } else { - return getFormatterContext().getRelationNames().get(resultSetCounter - 1); - } - } - @Override public void writeStartResultSet(ColumnsHeader header) { super.writeStartResultSet(header); - resultSetCounter++; printStartElement(qname(XML_ELEMENT_RELATION), singleAttribute(qnameDK(XML_ATTRIBUTE_STATEMENT), getCurrentStatementName())); printTextElement(qname(XML_ELEMENT_NAME), null, getCurrentRelationName());