1.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java Sun Dec 22 22:02:44 2013 +0100
1.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java Sun Dec 22 23:31:55 2013 +0100
1.3 @@ -21,6 +21,7 @@
1.4 import static info.globalcode.sql.dk.Functions.isEmpty;
1.5 import static info.globalcode.sql.dk.Functions.equalz;
1.6 import info.globalcode.sql.dk.SQLCommand.COMMAND_TYPE;
1.7 +import java.io.OutputStream;
1.8 import java.util.ArrayList;
1.9 import java.util.Collection;
1.10 import java.util.EnumSet;
1.11 @@ -59,7 +60,7 @@
1.12 CONNECTION
1.13 }
1.14 private COMMAND_TYPE commandType;
1.15 - private final Collection<NamedParameter> namedParameters = new ArrayList<>();
1.16 + private final List<NamedParameter> namedParameters = new ArrayList<>();
1.17 private final List<Parameter> numberedParameters = new ArrayList<>();
1.18 private final EnumSet<INFO_TYPE> showInfo = EnumSet.noneOf(INFO_TYPE.class);
1.19
1.20 @@ -207,4 +208,16 @@
1.21 public void setDatabaseNameToTest(String databaseNameToTest) {
1.22 this.databaseNameToTest = databaseNameToTest;
1.23 }
1.24 +
1.25 + public SQLCommand getSQLCommand() {
1.26 + if (namedParameters.isEmpty()) {
1.27 + return new SQLCommandNumbered(commandType, sql, numberedParameters);
1.28 + } else {
1.29 + return new SQLCommandNamed(commandType, sql, namedParameters);
1.30 + }
1.31 + }
1.32 +
1.33 + public OutputStream getOutputStream() {
1.34 + return System.out;
1.35 + }
1.36 }
2.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/CLIStarter.java Sun Dec 22 22:02:44 2013 +0100
2.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/CLIStarter.java Sun Dec 22 23:31:55 2013 +0100
2.3 @@ -21,7 +21,13 @@
2.4 import info.globalcode.sql.dk.CLIOptions.MODE;
2.5 import info.globalcode.sql.dk.configuration.Configuration;
2.6 import info.globalcode.sql.dk.configuration.ConfigurationException;
2.7 +import info.globalcode.sql.dk.configuration.DatabaseDefinition;
2.8 +import info.globalcode.sql.dk.configuration.FormatterDefinition;
2.9 +import info.globalcode.sql.dk.formatting.Formatter;
2.10 +import info.globalcode.sql.dk.formatting.FormatterContext;
2.11 +import info.globalcode.sql.dk.formatting.FormatterException;
2.12 import java.io.IOException;
2.13 +import java.sql.SQLException;
2.14 import java.util.logging.Level;
2.15 import java.util.logging.Logger;
2.16 import javax.xml.bind.JAXBContext;
2.17 @@ -54,6 +60,12 @@
2.18 log.log(Level.SEVERE, "Unable to parse CLI options", e);
2.19 } catch (InvalidOptionsException e) {
2.20 log.log(Level.SEVERE, "Invalid CLI options", e);
2.21 + } catch (ConfigurationException e) {
2.22 + log.log(Level.SEVERE, "Configuration problem", e);
2.23 + } catch (SQLException e) {
2.24 + log.log(Level.SEVERE, "SQL problem", e);
2.25 + } catch (FormatterException e) {
2.26 + log.log(Level.SEVERE, "Formatting problem", e);
2.27 }
2.28 }
2.29
2.30 @@ -61,7 +73,7 @@
2.31 this.options = options;
2.32 }
2.33
2.34 - private void process() {
2.35 + private void process() throws ConfigurationException, SQLException, FormatterException {
2.36 /** Show info */
2.37 if (!options.getShowInfo().isEmpty()) {
2.38 InfoLister infoLister = new InfoLister(System.err, this);
2.39 @@ -71,10 +83,13 @@
2.40 MODE mode = options.getMode();
2.41 switch (mode) {
2.42 case QUERY_NOW:
2.43 + processQueryNow();
2.44 break;
2.45 case PREPARE_BATCH:
2.46 + processPrepareBatch();
2.47 break;
2.48 case EXECUTE_BATCH:
2.49 + processExecuteBatch();
2.50 break;
2.51 case JUST_SHOW_INFO:
2.52 // already done above
2.53 @@ -85,6 +100,28 @@
2.54 }
2.55 }
2.56
2.57 + private void processQueryNow() throws ConfigurationException, SQLException, FormatterException {
2.58 + DatabaseDefinition dd = getConfiguration().getDatabase(options.getDatabaseName());
2.59 + if (dd == null) {
2.60 + throw new ConfigurationException("Database is not configured: " + options.getDatabaseName());
2.61 + } else {
2.62 + FormatterDefinition fd = configuration.getFormatter(options.getFormatterName());
2.63 + if (fd == null) {
2.64 + throw new ConfigurationException("Formatter is not configured: " + options.getDatabaseName());
2.65 + } else {
2.66 + DatabaseConnection c = dd.connect();
2.67 + Formatter f = fd.getInstance(new FormatterContext(options.getOutputStream()));
2.68 + c.executeQuery(options.getSQLCommand(), f);
2.69 + }
2.70 + }
2.71 + }
2.72 +
2.73 + private void processPrepareBatch() {
2.74 + }
2.75 +
2.76 + private void processExecuteBatch() {
2.77 + }
2.78 +
2.79 @Override
2.80 public Configuration getConfiguration() throws ConfigurationException {
2.81 if (configuration == null) {
2.82 @@ -93,7 +130,7 @@
2.83 return configuration;
2.84 }
2.85
2.86 - private void installDefaultConfiguration() {
2.87 + private void installDefaultConfiguration() throws ConfigurationException {
2.88 Constants.DIR.mkdir();
2.89
2.90 if (Constants.CONFIG_FILE.exists()) {
2.91 @@ -102,10 +139,9 @@
2.92 try {
2.93 Functions.installResource(Constants.EXAMPLE_CONFIG_FILE, Constants.CONFIG_FILE);
2.94 } catch (IOException e) {
2.95 - log.log(Level.SEVERE, "Unable to write example configuration to " + Constants.CONFIG_FILE, e);
2.96 + throw new ConfigurationException("Unable to write example configuration to " + Constants.CONFIG_FILE, e);
2.97 }
2.98 }
2.99 -
2.100 }
2.101
2.102 private Configuration loadConfiguration() throws ConfigurationException {
3.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java Sun Dec 22 22:02:44 2013 +0100
3.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java Sun Dec 22 23:31:55 2013 +0100
3.3 @@ -19,6 +19,7 @@
3.4
3.5 import info.globalcode.sql.dk.batch.Batch;
3.6 import info.globalcode.sql.dk.configuration.DatabaseDefinition;
3.7 +import info.globalcode.sql.dk.formatting.ColumnsHeader;
3.8 import info.globalcode.sql.dk.formatting.Formatter;
3.9 import java.sql.Connection;
3.10 import java.sql.DriverManager;
3.11 @@ -38,7 +39,7 @@
3.12 public DatabaseConnection(DatabaseDefinition databaseDefinition) throws SQLException {
3.13 this.databaseDefinition = databaseDefinition;
3.14
3.15 - connection = DriverManager.getConnection(databaseDefinition.getUrl(), databaseDefinition.getName(), databaseDefinition.getPassword());
3.16 + connection = DriverManager.getConnection(databaseDefinition.getUrl(), databaseDefinition.getUserName(), databaseDefinition.getPassword());
3.17 }
3.18
3.19 public void executeQuery(SQLCommand sqlCommand, Formatter formatter) throws SQLException {
3.20 @@ -72,7 +73,7 @@
3.21 private void processQueryCommand(SQLCommand sqlCommand, Formatter formatter) throws SQLException {
3.22 formatter.writeStartResultSet();
3.23 formatter.writeQuery(sqlCommand.getQuery());
3.24 - /** TODO: formatter.writeParameters(null); */
3.25 + formatter.writeParameters(sqlCommand.getParameters());
3.26 try (PreparedStatement ps = sqlCommand.prepareStatement(connection)) {
3.27 sqlCommand.parametrize(ps);
3.28 try (ResultSet rs = ps.executeQuery()) {
3.29 @@ -86,7 +87,7 @@
3.30 private void processUpdateCommand(SQLCommand sqlCommand, Formatter formatter) throws SQLException {
3.31 formatter.writeStartUpdatesResult();
3.32 formatter.writeQuery(sqlCommand.getQuery());
3.33 - /** TODO: formatter.writeParameters(null); */
3.34 + formatter.writeParameters(sqlCommand.getParameters());
3.35 try (PreparedStatement ps = sqlCommand.prepareStatement(connection)) {
3.36 sqlCommand.parametrize(ps);
3.37 int updatedRowsCount = ps.executeUpdate();
3.38 @@ -104,12 +105,18 @@
3.39 }
3.40
3.41 private void processResultSet(ResultSet rs, Formatter formatter) throws SQLException {
3.42 - /** TODO: formatter.writeColumnsHeader(null); */
3.43 + formatter.writeColumnsHeader(new ColumnsHeader(rs.getMetaData()));
3.44 + int columnCount = rs.getMetaData().getColumnCount();
3.45 +
3.46 while (rs.next()) {
3.47 formatter.writeStartRow();
3.48
3.49 - /** TODO: formatter.writeColumnValue(rs.get); */
3.50 + for (int i = 1; i <= columnCount; i++) {
3.51 + formatter.writeColumnValue(rs.getObject(i));
3.52 + }
3.53 +
3.54 formatter.writeEndRow();
3.55 }
3.56 +
3.57 }
3.58 }
4.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/Functions.java Sun Dec 22 22:02:44 2013 +0100
4.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/Functions.java Sun Dec 22 23:31:55 2013 +0100
4.3 @@ -26,7 +26,6 @@
4.4 import java.util.ArrayList;
4.5 import java.util.Collection;
4.6 import java.util.Map;
4.7 -import java.util.logging.Level;
4.8
4.9 /**
4.10 *
5.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/SQLCommand.java Sun Dec 22 22:02:44 2013 +0100
5.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/SQLCommand.java Sun Dec 22 23:31:55 2013 +0100
5.3 @@ -19,6 +19,8 @@
5.4
5.5 import java.sql.Connection;
5.6 import java.sql.PreparedStatement;
5.7 +import java.sql.SQLException;
5.8 +import java.util.List;
5.9
5.10 /**
5.11 *
5.12 @@ -29,9 +31,16 @@
5.13 private COMMAND_TYPE commandType;
5.14 private String query;
5.15
5.16 - public abstract PreparedStatement prepareStatement(Connection c);
5.17 + public SQLCommand(COMMAND_TYPE commandType, String query) {
5.18 + this.commandType = commandType;
5.19 + this.query = query;
5.20 + }
5.21
5.22 - public abstract void parametrize(PreparedStatement ps);
5.23 + public abstract PreparedStatement prepareStatement(Connection c) throws SQLException;
5.24 +
5.25 + public abstract void parametrize(PreparedStatement ps) throws SQLException;
5.26 +
5.27 + public abstract List<? extends Parameter> getParameters();
5.28
5.29 public COMMAND_TYPE getCommandType() {
5.30 return commandType;
6.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNamed.java Sun Dec 22 22:02:44 2013 +0100
6.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNamed.java Sun Dec 22 23:31:55 2013 +0100
6.3 @@ -19,6 +19,8 @@
6.4
6.5 import java.sql.Connection;
6.6 import java.sql.PreparedStatement;
6.7 +import java.sql.SQLException;
6.8 +import java.util.List;
6.9
6.10 /**
6.11 *
6.12 @@ -26,13 +28,25 @@
6.13 */
6.14 public class SQLCommandNamed extends SQLCommand {
6.15
6.16 + private List<NamedParameter> parameters;
6.17 +
6.18 + public SQLCommandNamed(COMMAND_TYPE commandType, String query, List<NamedParameter> parameters) {
6.19 + super(commandType, query);
6.20 + this.parameters = parameters;
6.21 + }
6.22 +
6.23 @Override
6.24 - public PreparedStatement prepareStatement(Connection c) {
6.25 + public PreparedStatement prepareStatement(Connection c) throws SQLException {
6.26 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
6.27 }
6.28
6.29 @Override
6.30 - public void parametrize(PreparedStatement ps) {
6.31 + public void parametrize(PreparedStatement ps) throws SQLException {
6.32 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
6.33 }
6.34 +
6.35 + @Override
6.36 + public List<NamedParameter> getParameters() {
6.37 + return parameters;
6.38 + }
6.39 }
7.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNumbered.java Sun Dec 22 22:02:44 2013 +0100
7.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNumbered.java Sun Dec 22 23:31:55 2013 +0100
7.3 @@ -17,8 +17,11 @@
7.4 */
7.5 package info.globalcode.sql.dk;
7.6
7.7 +import static info.globalcode.sql.dk.Functions.notNull;
7.8 import java.sql.Connection;
7.9 import java.sql.PreparedStatement;
7.10 +import java.sql.SQLException;
7.11 +import java.util.List;
7.12
7.13 /**
7.14 *
7.15 @@ -26,13 +29,28 @@
7.16 */
7.17 public class SQLCommandNumbered extends SQLCommand {
7.18
7.19 - @Override
7.20 - public PreparedStatement prepareStatement(Connection c) {
7.21 - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
7.22 + private List<Parameter> parameters;
7.23 +
7.24 + public SQLCommandNumbered(COMMAND_TYPE commandType, String query, List<Parameter> parameters) {
7.25 + super(commandType, query);
7.26 + this.parameters = parameters;
7.27 }
7.28
7.29 @Override
7.30 - public void parametrize(PreparedStatement ps) {
7.31 - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
7.32 + public PreparedStatement prepareStatement(Connection c) throws SQLException {
7.33 + return c.prepareStatement(getQuery());
7.34 + }
7.35 +
7.36 + @Override
7.37 + public void parametrize(PreparedStatement ps) throws SQLException {
7.38 + int i = 1;
7.39 + for (Parameter p : notNull(parameters)) {
7.40 + ps.setObject(i++, p.getValue(), p.getType());
7.41 + }
7.42 + }
7.43 +
7.44 + @Override
7.45 + public List<Parameter> getParameters() {
7.46 + return parameters;
7.47 }
7.48 }
8.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/configuration/FormatterDefinition.java Sun Dec 22 22:02:44 2013 +0100
8.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/configuration/FormatterDefinition.java Sun Dec 22 23:31:55 2013 +0100
8.3 @@ -21,6 +21,7 @@
8.4 import info.globalcode.sql.dk.DKException;
8.5 import info.globalcode.sql.dk.formatting.Formatter;
8.6 import info.globalcode.sql.dk.formatting.FormatterContext;
8.7 +import info.globalcode.sql.dk.formatting.FormatterException;
8.8 import java.lang.reflect.Constructor;
8.9 import java.lang.reflect.InvocationTargetException;
8.10 import javax.xml.bind.annotation.XmlElement;
8.11 @@ -76,7 +77,7 @@
8.12 * @return
8.13 * @throws DKException
8.14 */
8.15 - public Formatter getInstance(FormatterContext context) throws DKException {
8.16 + public Formatter getInstance(FormatterContext context) throws FormatterException {
8.17 try {
8.18 Constructor constructor = Class.forName(className).getConstructor(context.getClass());
8.19
8.20 @@ -84,14 +85,14 @@
8.21 if (instance instanceof Formatter) {
8.22 return (Formatter) instance;
8.23 } else {
8.24 - throw new DKException("Formatter " + instance + " does not implement the " + Formatter.class.getName() + " interface");
8.25 + throw new FormatterException("Formatter " + instance + " does not implement the " + Formatter.class.getName() + " interface");
8.26 }
8.27 } catch (ClassNotFoundException e) {
8.28 - throw new DKException("No formatter class with name: " + className, e);
8.29 + throw new FormatterException("No formatter class with name: " + className, e);
8.30 } catch (NoSuchMethodException e) {
8.31 - throw new DKException("Formatter class with no valid constructor: " + className, e);
8.32 + throw new FormatterException("Formatter class with no valid constructor: " + className, e);
8.33 } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
8.34 - throw new DKException("Formatter's constructor caused an error: " + className, e);
8.35 + throw new FormatterException("Formatter's constructor caused an error: " + className, e);
8.36 }
8.37 }
8.38 }
9.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/AbstractFormatter.java Sun Dec 22 22:02:44 2013 +0100
9.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/AbstractFormatter.java Sun Dec 22 23:31:55 2013 +0100
9.3 @@ -110,7 +110,8 @@
9.4 */
9.5 private State popState(EnumSet expected) {
9.6 try {
9.7 - State superior = state.pop();
9.8 + state.pop();
9.9 + State superior = state.peek();
9.10 if (expected.contains(superior)) {
9.11 return superior;
9.12 } else {
9.13 @@ -155,7 +156,7 @@
9.14 }
9.15
9.16 @Override
9.17 - public void writeParameters(List<Parameter> parameters) {
9.18 + public void writeParameters(List<? extends Parameter> parameters) {
9.19 peekState(EnumSet.of(State.RESULT_SET, State.UPDATES_RESULT));
9.20
9.21 if (currentColumnsHeader != null) {
9.22 @@ -242,6 +243,14 @@
9.23 return currentColumnsCount;
9.24 }
9.25
9.26 + protected boolean isCurrentColumnFirst() {
9.27 + return currentColumnsCount == 1;
9.28 + }
9.29 +
9.30 + protected boolean isCurrentColumnLast() {
9.31 + return currentColumnsCount == currentColumnsHeader.getColumnCount();
9.32 + }
9.33 +
9.34 /**
9.35 * @return row number, 1 = first
9.36 */
10.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/Formatter.java Sun Dec 22 22:02:44 2013 +0100
10.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/Formatter.java Sun Dec 22 23:31:55 2013 +0100
10.3 @@ -37,7 +37,7 @@
10.4
10.5 void writeQuery(String sql);
10.6
10.7 - void writeParameters(List<Parameter> parameters);
10.8 + void writeParameters(List<? extends Parameter> parameters);
10.9
10.10 void writeColumnsHeader(ColumnsHeader header);
10.11
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/FormatterException.java Sun Dec 22 23:31:55 2013 +0100
11.3 @@ -0,0 +1,42 @@
11.4 +/**
11.5 + * SQL-DK
11.6 + * Copyright © 2013 František Kučera (frantovo.cz)
11.7 + *
11.8 + * This program is free software: you can redistribute it and/or modify
11.9 + * it under the terms of the GNU General Public License as published by
11.10 + * the Free Software Foundation, either version 3 of the License, or
11.11 + * (at your option) any later version.
11.12 + *
11.13 + * This program is distributed in the hope that it will be useful,
11.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.16 + * GNU General Public License for more details.
11.17 + *
11.18 + * You should have received a copy of the GNU General Public License
11.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
11.20 + */
11.21 +package info.globalcode.sql.dk.formatting;
11.22 +
11.23 +import info.globalcode.sql.dk.DKException;
11.24 +
11.25 +/**
11.26 + *
11.27 + * @author Ing. František Kučera (frantovo.cz)
11.28 + */
11.29 +public class FormatterException extends DKException {
11.30 +
11.31 + public FormatterException() {
11.32 + }
11.33 +
11.34 + public FormatterException(String message) {
11.35 + super(message);
11.36 + }
11.37 +
11.38 + public FormatterException(Throwable cause) {
11.39 + super(cause);
11.40 + }
11.41 +
11.42 + public FormatterException(String message, Throwable cause) {
11.43 + super(message, cause);
11.44 + }
11.45 +}
12.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/TabularFormatter.java Sun Dec 22 22:02:44 2013 +0100
12.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/TabularFormatter.java Sun Dec 22 23:31:55 2013 +0100
12.3 @@ -17,6 +17,8 @@
12.4 */
12.5 package info.globalcode.sql.dk.formatting;
12.6
12.7 +import info.globalcode.sql.dk.ColorfulPrintWriter;
12.8 +
12.9 /**
12.10 *
12.11 * @author Ing. František Kučera (frantovo.cz)
12.12 @@ -24,8 +26,28 @@
12.13 public class TabularFormatter extends AbstractFormatter {
12.14
12.15 public static final String NAME = "tabular";
12.16 + private ColorfulPrintWriter out;
12.17
12.18 public TabularFormatter(FormatterContext formatterContext) {
12.19 super(formatterContext);
12.20 + out = new ColorfulPrintWriter(formatterContext.getOutputStream());
12.21 + }
12.22 +
12.23 + @Override
12.24 + public void writeColumnValue(Object value) {
12.25 + super.writeColumnValue(value);
12.26 +
12.27 + if (!isCurrentColumnFirst()) {
12.28 + out.print(ColorfulPrintWriter.TerminalColor.Green, " | ");
12.29 + }
12.30 +
12.31 + out.print(ColorfulPrintWriter.TerminalColor.Cyan, String.valueOf(value));
12.32 + }
12.33 +
12.34 + @Override
12.35 + public void writeEndRow() {
12.36 + super.writeEndRow();
12.37 + out.println();
12.38 + out.flush();
12.39 }
12.40 }