# HG changeset patch # User František Kučera # Date 1387795824 -3600 # Node ID 9e6f8e5d5f98bd14dadcfb881575146082e3265b # Parent 025fbe816bbfb5fdcd8f027bf2ac1880bf445796 support SQL commands returning more ResultSets + remove COMMAND_TYPE (type is now derived from result returned from SQL – it is not needed to specify the type on CLI) diff -r 025fbe816bbf -r 9e6f8e5d5f98 java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java --- a/java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java Mon Dec 23 00:14:29 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java Mon Dec 23 11:50:24 2013 +0100 @@ -20,7 +20,6 @@ import static info.globalcode.sql.dk.Functions.isNotEmpty; import static info.globalcode.sql.dk.Functions.isEmpty; import static info.globalcode.sql.dk.Functions.equalz; -import info.globalcode.sql.dk.SQLCommand.COMMAND_TYPE; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; @@ -59,7 +58,6 @@ DATABASES, CONNECTION } - private COMMAND_TYPE commandType; private final List namedParameters = new ArrayList<>(); private final List numberedParameters = new ArrayList<>(); private final EnumSet showInfo = EnumSet.noneOf(INFO_TYPE.class); @@ -153,14 +151,6 @@ this.batch = batch; } - public COMMAND_TYPE getCommandType() { - return commandType; - } - - public void setCommandType(COMMAND_TYPE commandType) { - this.commandType = commandType; - } - public Collection getNamedParameters() { return namedParameters; } @@ -211,9 +201,9 @@ public SQLCommand getSQLCommand() { if (namedParameters.isEmpty()) { - return new SQLCommandNumbered(commandType, sql, numberedParameters); + return new SQLCommandNumbered(sql, numberedParameters); } else { - return new SQLCommandNamed(commandType, sql, namedParameters); + return new SQLCommandNamed(sql, namedParameters); } } diff -r 025fbe816bbf -r 9e6f8e5d5f98 java/sql-dk/src/info/globalcode/sql/dk/CLIParser.java --- a/java/sql-dk/src/info/globalcode/sql/dk/CLIParser.java Mon Dec 23 00:14:29 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/CLIParser.java Mon Dec 23 11:50:24 2013 +0100 @@ -17,7 +17,6 @@ */ package info.globalcode.sql.dk; -import info.globalcode.sql.dk.SQLCommand.COMMAND_TYPE; import java.sql.Types; import java.util.ArrayList; import java.util.Collections; @@ -76,12 +75,6 @@ break; case Tokens.SQL: options.setSql(fetchNext(args, ++i)); - options.setCommandType(COMMAND_TYPE.QUERY); - break; - case Tokens.SQL_UPDATE: - case Tokens.SQL_INSERT: - options.setSql(fetchNext(args, ++i)); - options.setCommandType(COMMAND_TYPE.UPDATE); break; case Tokens.BATCH: options.setBatch(true); @@ -158,8 +151,6 @@ public static final String DB = "--db"; public static final String SQL = "--sql"; - public static final String SQL_UPDATE = "--sql-update"; - public static final String SQL_INSERT = "--sql-insert"; public static final String BATCH = "--batch"; public static final String DATA = "--data"; public static final String NAME_PREFIX = "--name-prefix"; diff -r 025fbe816bbf -r 9e6f8e5d5f98 java/sql-dk/src/info/globalcode/sql/dk/ColorfulPrintWriter.java --- a/java/sql-dk/src/info/globalcode/sql/dk/ColorfulPrintWriter.java Mon Dec 23 00:14:29 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/ColorfulPrintWriter.java Mon Dec 23 11:50:24 2013 +0100 @@ -166,6 +166,26 @@ println(); } + public void print(EnumSet styles, String string) { + setStyle(styles); + print(string); + resetAll(); + } + + public void println(EnumSet styles, String string) { + print(styles, string); + println(); + } + + public void print(TerminalStyle style, String string) { + print(EnumSet.of(style), string); + } + + public void println(TerminalStyle style, String string) { + print(style, string); + println(); + } + public void resetAll() { printCodes(0); } diff -r 025fbe816bbf -r 9e6f8e5d5f98 java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java --- a/java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java Mon Dec 23 00:14:29 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java Mon Dec 23 11:50:24 2013 +0100 @@ -57,68 +57,58 @@ } private void processCommand(SQLCommand sqlCommand, Formatter formatter) throws SQLException { - SQLCommand.COMMAND_TYPE commandType = sqlCommand.getCommandType(); - switch (commandType) { - case QUERY: - processQueryCommand(sqlCommand, formatter); - break; - case UPDATE: - processUpdateCommand(sqlCommand, formatter); - break; - default: - throw new IllegalArgumentException("Unexpected command type: " + commandType); - } - } - - private void processQueryCommand(SQLCommand sqlCommand, Formatter formatter) throws SQLException { - formatter.writeStartResultSet(); - formatter.writeQuery(sqlCommand.getQuery()); - formatter.writeParameters(sqlCommand.getParameters()); try (PreparedStatement ps = sqlCommand.prepareStatement(connection)) { sqlCommand.parametrize(ps); boolean isRS = ps.execute(); if (isRS) { try (ResultSet rs = ps.getResultSet()) { - processResultSet(rs, formatter); + processResultSet(sqlCommand, rs, formatter); } } else { - /** - * TODO: process UPDATE command - */ + processUpdateResult(sqlCommand, ps, formatter); } while (ps.getMoreResults() || ps.getUpdateCount() > -1) { - /** - * TODO: process more RS or UPDATEs - */ + ResultSet rs = ps.getResultSet(); + if (rs == null) { + processUpdateResult(sqlCommand, ps, formatter); + } else { + processResultSet(sqlCommand, rs, formatter); + rs.close(); + } } } + } + + private void processUpdateResult(SQLCommand sqlCommand, PreparedStatement ps, Formatter formatter) throws SQLException { + formatter.writeStartUpdatesResult(); + formatter.writeQuery(sqlCommand.getQuery()); + formatter.writeParameters(sqlCommand.getParameters()); + + int updatedRowsCount = ps.getUpdateCount(); + formatter.writeUpdatedRowsCount(updatedRowsCount); + + formatter.writeStartGeneratedKeys(); + try (ResultSet rs = ps.getGeneratedKeys()) { + processResultSetRows(rs, formatter); + } + formatter.writeEndGeneratedKeys(); + + formatter.writeEndUpdatesResult(); + } + + private void processResultSet(SQLCommand sqlCommand, ResultSet rs, Formatter formatter) throws SQLException { + formatter.writeStartResultSet(); + formatter.writeQuery(sqlCommand.getQuery()); + formatter.writeParameters(sqlCommand.getParameters()); + + processResultSetRows(rs, formatter); formatter.writeEndResultSet(); } - private void processUpdateCommand(SQLCommand sqlCommand, Formatter formatter) throws SQLException { - formatter.writeStartUpdatesResult(); - formatter.writeQuery(sqlCommand.getQuery()); - formatter.writeParameters(sqlCommand.getParameters()); - try (PreparedStatement ps = sqlCommand.prepareStatement(connection)) { - sqlCommand.parametrize(ps); - int updatedRowsCount = ps.executeUpdate(); - formatter.writeUpdatedRowsCount(updatedRowsCount); - - formatter.writeStartGeneratedKeys(); - try (ResultSet rs = ps.getGeneratedKeys()) { - processResultSet(rs, formatter); - } - formatter.writeEndGeneratedKeys(); - - } - - formatter.writeEndUpdatesResult(); - } - - private void processResultSet(ResultSet rs, Formatter formatter) throws SQLException { + private void processResultSetRows(ResultSet rs, Formatter formatter) throws SQLException { formatter.writeColumnsHeader(new ColumnsHeader(rs.getMetaData())); int columnCount = rs.getMetaData().getColumnCount(); diff -r 025fbe816bbf -r 9e6f8e5d5f98 java/sql-dk/src/info/globalcode/sql/dk/SQLCommand.java --- a/java/sql-dk/src/info/globalcode/sql/dk/SQLCommand.java Mon Dec 23 00:14:29 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/SQLCommand.java Mon Dec 23 11:50:24 2013 +0100 @@ -28,11 +28,9 @@ */ public abstract class SQLCommand { - private COMMAND_TYPE commandType; private String query; - public SQLCommand(COMMAND_TYPE commandType, String query) { - this.commandType = commandType; + public SQLCommand(String query) { this.query = query; } @@ -44,23 +42,7 @@ public abstract List getParameters(); - public COMMAND_TYPE getCommandType() { - return commandType; - } - - public void setCommandType(COMMAND_TYPE commandType) { - this.commandType = commandType; - } - public String getQuery() { return query; } - - public enum COMMAND_TYPE { - - /** SELECT */ - QUERY, - /** INSERT, UPDATE, DELETE */ - UPDATE - }; } diff -r 025fbe816bbf -r 9e6f8e5d5f98 java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNamed.java --- a/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNamed.java Mon Dec 23 00:14:29 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNamed.java Mon Dec 23 11:50:24 2013 +0100 @@ -17,7 +17,6 @@ */ package info.globalcode.sql.dk; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; @@ -30,8 +29,8 @@ private List parameters; - public SQLCommandNamed(COMMAND_TYPE commandType, String query, List parameters) { - super(commandType, query); + public SQLCommandNamed(String query, List parameters) { + super(query); this.parameters = parameters; } diff -r 025fbe816bbf -r 9e6f8e5d5f98 java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNumbered.java --- a/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNumbered.java Mon Dec 23 00:14:29 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNumbered.java Mon Dec 23 11:50:24 2013 +0100 @@ -18,7 +18,6 @@ package info.globalcode.sql.dk; import static info.globalcode.sql.dk.Functions.notNull; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; @@ -31,8 +30,8 @@ private List parameters; - public SQLCommandNumbered(COMMAND_TYPE commandType, String query, List parameters) { - super(commandType, query); + public SQLCommandNumbered(String query, List parameters) { + super(query); this.parameters = parameters; } diff -r 025fbe816bbf -r 9e6f8e5d5f98 java/sql-dk/src/info/globalcode/sql/dk/formatting/AbstractFormatter.java --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/AbstractFormatter.java Mon Dec 23 00:14:29 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/AbstractFormatter.java Mon Dec 23 11:50:24 2013 +0100 @@ -170,7 +170,7 @@ @Override public void writeColumnsHeader(ColumnsHeader header) { - peekState(EnumSet.of(State.RESULT_SET, State.UPDATES_RESULT)); + peekState(EnumSet.of(State.RESULT_SET, State.GENERATED_KEYS)); if (currentColumnsHeader == null) { currentColumnsHeader = header; @@ -204,7 +204,7 @@ @Override public void writeStartUpdatesResult() { - pushState(State.RESULT_SET, EnumSet.of(State.DATABASE)); + pushState(State.UPDATES_RESULT, EnumSet.of(State.DATABASE)); } @Override diff -r 025fbe816bbf -r 9e6f8e5d5f98 java/sql-dk/src/info/globalcode/sql/dk/formatting/ColumnDescriptor.java --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/ColumnDescriptor.java Mon Dec 23 00:14:29 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/ColumnDescriptor.java Mon Dec 23 11:50:24 2013 +0100 @@ -27,7 +27,13 @@ private String label; private int type; private String typeName; + private boolean firstColumn; + private boolean lastColumn; + /** + * @return column name + * @see #getLabel() + */ public String getName() { return name; } @@ -36,6 +42,9 @@ this.name = name; } + /** + * @return label specified by the SQL AS clause + */ public String getLabel() { return label; } @@ -59,4 +68,20 @@ public void setTypeName(String typeName) { this.typeName = typeName; } + + public boolean isFirstColumn() { + return firstColumn; + } + + public void setFirstColumn(boolean firstColumn) { + this.firstColumn = firstColumn; + } + + public boolean isLastColumn() { + return lastColumn; + } + + public void setLastColumn(boolean lastColumn) { + this.lastColumn = lastColumn; + } } diff -r 025fbe816bbf -r 9e6f8e5d5f98 java/sql-dk/src/info/globalcode/sql/dk/formatting/ColumnsHeader.java --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/ColumnsHeader.java Mon Dec 23 00:14:29 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/ColumnsHeader.java Mon Dec 23 11:50:24 2013 +0100 @@ -28,7 +28,7 @@ */ public class ColumnsHeader { - ResultSetMetaData metaData; + private ResultSetMetaData metaData; public ColumnsHeader(ResultSetMetaData metaData) { this.metaData = metaData; @@ -49,6 +49,8 @@ for (int i = 1; i <= count; i++) { ColumnDescriptor cd = new ColumnDescriptor(); + cd.setFirstColumn(i == 1); + cd.setLastColumn(i == count); cd.setLabel(metaData.getColumnLabel(i)); cd.setName(metaData.getColumnName(i)); cd.setType(metaData.getColumnType(i)); diff -r 025fbe816bbf -r 9e6f8e5d5f98 java/sql-dk/src/info/globalcode/sql/dk/formatting/TabularFormatter.java --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/TabularFormatter.java Mon Dec 23 00:14:29 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/TabularFormatter.java Mon Dec 23 11:50:24 2013 +0100 @@ -18,6 +18,7 @@ package info.globalcode.sql.dk.formatting; import info.globalcode.sql.dk.ColorfulPrintWriter; +import static info.globalcode.sql.dk.ColorfulPrintWriter.*; /** * @@ -27,6 +28,7 @@ public static final String NAME = "tabular"; private ColorfulPrintWriter out; + private boolean firstResult = true; public TabularFormatter(FormatterContext formatterContext) { super(formatterContext); @@ -34,14 +36,37 @@ } @Override + public void writeStartResultSet() { + super.writeStartResultSet(); + printResultSeparator(); + } + + @Override + public void writeColumnsHeader(ColumnsHeader header) { + super.writeColumnsHeader(header); + + for (ColumnDescriptor cd : header.getColumnDescriptors()) { + out.print(TerminalStyle.Bright, cd.getLabel()); + out.print(" ("); + out.print(cd.getTypeName()); + out.print(")"); + if (!cd.isLastColumn()) { + out.print(TerminalColor.Green, " | "); + } + } + out.println(); + out.flush(); + } + + @Override public void writeColumnValue(Object value) { super.writeColumnValue(value); if (!isCurrentColumnFirst()) { - out.print(ColorfulPrintWriter.TerminalColor.Green, " | "); + out.print(TerminalColor.Green, " | "); } - - out.print(ColorfulPrintWriter.TerminalColor.Cyan, String.valueOf(value)); + + out.print(TerminalColor.Cyan, String.valueOf(value)); } @Override @@ -50,4 +75,40 @@ out.println(); out.flush(); } + + @Override + public void writeEndResultSet() { + super.writeEndResultSet(); + out.print(TerminalColor.Yellow, "Record count: "); + out.println(getCurrentRowCount()); + out.flush(); + } + + @Override + public void writeStartUpdatesResult() { + super.writeStartUpdatesResult(); + printResultSeparator(); + } + + @Override + public void writeUpdatedRowsCount(int updatedRowsCount) { + super.writeUpdatedRowsCount(updatedRowsCount); + out.print(TerminalColor.Red, "Updated records: "); + out.println(updatedRowsCount); + out.flush(); + } + + @Override + public void writeEndDatabase() { + super.writeEndDatabase(); + out.flush(); + } + + private void printResultSeparator() { + if (firstResult) { + firstResult = false; + } else { + out.println(); + } + } }