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) v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Mon, 23 Dec 2013 11:50:24 +0100
branchv_0
changeset 37 9e6f8e5d5f98
parent 36 025fbe816bbf
child 38 ff5bbc06ed29
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)
java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java
java/sql-dk/src/info/globalcode/sql/dk/CLIParser.java
java/sql-dk/src/info/globalcode/sql/dk/ColorfulPrintWriter.java
java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java
java/sql-dk/src/info/globalcode/sql/dk/SQLCommand.java
java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNamed.java
java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNumbered.java
java/sql-dk/src/info/globalcode/sql/dk/formatting/AbstractFormatter.java
java/sql-dk/src/info/globalcode/sql/dk/formatting/ColumnDescriptor.java
java/sql-dk/src/info/globalcode/sql/dk/formatting/ColumnsHeader.java
java/sql-dk/src/info/globalcode/sql/dk/formatting/TabularFormatter.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<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();
+		}
+	}
 }