24 import static info.globalcode.sql.dk.Functions.rpad; |
24 import static info.globalcode.sql.dk.Functions.rpad; |
25 import static info.globalcode.sql.dk.Functions.repeat; |
25 import static info.globalcode.sql.dk.Functions.repeat; |
26 import info.globalcode.sql.dk.configuration.PropertyDeclaration; |
26 import info.globalcode.sql.dk.configuration.PropertyDeclaration; |
27 import static info.globalcode.sql.dk.formatting.CommonProperties.COLORFUL; |
27 import static info.globalcode.sql.dk.formatting.CommonProperties.COLORFUL; |
28 import static info.globalcode.sql.dk.formatting.CommonProperties.COLORFUL_DESCRIPTION; |
28 import static info.globalcode.sql.dk.formatting.CommonProperties.COLORFUL_DESCRIPTION; |
|
29 import java.sql.SQLException; |
|
30 import java.sql.SQLXML; |
29 import java.util.List; |
31 import java.util.List; |
|
32 import java.util.logging.Level; |
|
33 import java.util.logging.Logger; |
30 |
34 |
31 /** |
35 /** |
32 * <p> |
36 * <p> |
33 * Prints human-readable output – tables of result sets and text messages with update counts. |
37 * Prints human-readable output – tables of result sets and text messages with update counts. |
34 * </p> |
38 * </p> |
35 * |
39 * |
36 * <p> |
40 * <p> |
37 * Longer values might break the table – overflow the cells – see alternative tabular formatters |
41 * Longer values might break the table – overflow the cells – see alternative tabular formatters and |
38 * and the {@linkplain #PROPERTY_TRIM} property. |
42 * the {@linkplain #PROPERTY_TRIM} property. |
39 * </p> |
43 * </p> |
40 * |
44 * |
41 * @author Ing. František Kučera (frantovo.cz) |
45 * @author Ing. František Kučera (frantovo.cz) |
42 * @see TabularPrefetchingFormatter |
46 * @see TabularPrefetchingFormatter |
43 * @see TabularWrappingFormatter |
47 * @see TabularWrappingFormatter |
46 @PropertyDeclaration(name = TabularFormatter.PROPERTY_ASCII, defaultValue = "false", type = Boolean.class, description = "whether to use ASCII table borders instead of unicode ones") |
50 @PropertyDeclaration(name = TabularFormatter.PROPERTY_ASCII, defaultValue = "false", type = Boolean.class, description = "whether to use ASCII table borders instead of unicode ones") |
47 @PropertyDeclaration(name = TabularFormatter.PROPERTY_TRIM, defaultValue = "false", type = Boolean.class, description = "whether to trim the values to fit the column width") |
51 @PropertyDeclaration(name = TabularFormatter.PROPERTY_TRIM, defaultValue = "false", type = Boolean.class, description = "whether to trim the values to fit the column width") |
48 @PropertyDeclaration(name = TabularFormatter.PROPERTY_HEADER_TYPE, defaultValue = "true", type = Boolean.class, description = "whether to print data types in column headers") |
52 @PropertyDeclaration(name = TabularFormatter.PROPERTY_HEADER_TYPE, defaultValue = "true", type = Boolean.class, description = "whether to print data types in column headers") |
49 public class TabularFormatter extends AbstractFormatter { |
53 public class TabularFormatter extends AbstractFormatter { |
50 |
54 |
|
55 private static final Logger log = Logger.getLogger(TabularFormatter.class.getName()); |
51 public static final String NAME = "tabular"; // bash-completion:formatter |
56 public static final String NAME = "tabular"; // bash-completion:formatter |
52 private static final String HEADER_TYPE_PREFIX = " ("; |
57 private static final String HEADER_TYPE_PREFIX = " ("; |
53 private static final String HEADER_TYPE_SUFFIX = ")"; |
58 private static final String HEADER_TYPE_SUFFIX = ")"; |
54 public static final String PROPERTY_ASCII = "ascii"; |
59 public static final String PROPERTY_ASCII = "ascii"; |
55 public static final String PROPERTY_TRIM = "trim"; |
60 public static final String PROPERTY_TRIM = "trim"; |
137 |
142 |
138 out.flush(); |
143 out.flush(); |
139 } |
144 } |
140 |
145 |
141 /** |
146 /** |
142 * Must be called before |
147 * Must be called before {@linkplain #updateColumnWidth(int, int)} and |
143 * {@linkplain #updateColumnWidth(int, int)} |
148 * {@linkplain #getColumnWidth(int)} for each result set. |
144 * and {@linkplain #getColumnWidth(int)} |
|
145 * for each result set. |
|
146 * |
149 * |
147 * @param columnCount number of columns in current result set |
150 * @param columnCount number of columns in current result set |
148 */ |
151 */ |
149 protected void initColumnWidths(int columnCount) { |
152 protected void initColumnWidths(int columnCount) { |
150 if (columnWidth == null) { |
153 if (columnWidth == null) { |
201 final int width = getColumnWidth(getCurrentColumnsCount()); |
204 final int width = getColumnWidth(getCurrentColumnsCount()); |
202 String result; |
205 String result; |
203 if (value instanceof Number || value instanceof Boolean) { |
206 if (value instanceof Number || value instanceof Boolean) { |
204 result = lpad(String.valueOf(value), width); |
207 result = lpad(String.valueOf(value), width); |
205 } else { |
208 } else { |
|
209 if (value instanceof SQLXML) { |
|
210 // TODO: move to a common method, share with other formatters |
|
211 try { |
|
212 value = ((SQLXML) value).getString(); |
|
213 } catch (SQLException e) { |
|
214 log.log(Level.SEVERE, "Unable to format XML", e); |
|
215 } |
|
216 } |
|
217 |
206 result = rpad(String.valueOf(value), width); |
218 result = rpad(String.valueOf(value), width); |
207 } |
219 } |
208 // ? value = (boolean) value ? "✔" : "✗"; |
220 // ? value = (boolean) value ? "✔" : "✗"; |
209 |
221 |
210 if (trimValues && result.length() > width) { |
222 if (trimValues && result.length() > width) { |