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)
--- 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<NamedParameter> namedParameters = new ArrayList<>();
private final List<Parameter> numberedParameters = new ArrayList<>();
private final EnumSet<INFO_TYPE> 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<NamedParameter> 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);
}
}
--- 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";
--- 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<TerminalStyle> styles, String string) {
+ setStyle(styles);
+ print(string);
+ resetAll();
+ }
+
+ public void println(EnumSet<TerminalStyle> 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);
}
--- 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();
--- 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<? extends Parameter> 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
- };
}
--- 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<NamedParameter> parameters;
- public SQLCommandNamed(COMMAND_TYPE commandType, String query, List<NamedParameter> parameters) {
- super(commandType, query);
+ public SQLCommandNamed(String query, List<NamedParameter> parameters) {
+ super(query);
this.parameters = parameters;
}
--- 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<Parameter> parameters;
- public SQLCommandNumbered(COMMAND_TYPE commandType, String query, List<Parameter> parameters) {
- super(commandType, query);
+ public SQLCommandNumbered(String query, List<Parameter> parameters) {
+ super(query);
this.parameters = parameters;
}
--- 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
--- 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;
+ }
}
--- 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));
--- 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();
+ }
+ }
}