# HG changeset patch # User František Kučera # Date 1387751515 -3600 # Node ID 9335cf31c0f2b068a75a49b660653ccc996b4c53 # Parent 04db6ccd6c48e5f6b60a04cb179b45431a6a6450 first working version diff -r 04db6ccd6c48 -r 9335cf31c0f2 java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java --- a/java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java Sun Dec 22 22:02:44 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java Sun Dec 22 23:31:55 2013 +0100 @@ -21,6 +21,7 @@ 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; import java.util.EnumSet; @@ -59,7 +60,7 @@ CONNECTION } private COMMAND_TYPE commandType; - private final Collection namedParameters = new ArrayList<>(); + private final List namedParameters = new ArrayList<>(); private final List numberedParameters = new ArrayList<>(); private final EnumSet showInfo = EnumSet.noneOf(INFO_TYPE.class); @@ -207,4 +208,16 @@ public void setDatabaseNameToTest(String databaseNameToTest) { this.databaseNameToTest = databaseNameToTest; } + + public SQLCommand getSQLCommand() { + if (namedParameters.isEmpty()) { + return new SQLCommandNumbered(commandType, sql, numberedParameters); + } else { + return new SQLCommandNamed(commandType, sql, namedParameters); + } + } + + public OutputStream getOutputStream() { + return System.out; + } } diff -r 04db6ccd6c48 -r 9335cf31c0f2 java/sql-dk/src/info/globalcode/sql/dk/CLIStarter.java --- a/java/sql-dk/src/info/globalcode/sql/dk/CLIStarter.java Sun Dec 22 22:02:44 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/CLIStarter.java Sun Dec 22 23:31:55 2013 +0100 @@ -21,7 +21,13 @@ import info.globalcode.sql.dk.CLIOptions.MODE; import info.globalcode.sql.dk.configuration.Configuration; import info.globalcode.sql.dk.configuration.ConfigurationException; +import info.globalcode.sql.dk.configuration.DatabaseDefinition; +import info.globalcode.sql.dk.configuration.FormatterDefinition; +import info.globalcode.sql.dk.formatting.Formatter; +import info.globalcode.sql.dk.formatting.FormatterContext; +import info.globalcode.sql.dk.formatting.FormatterException; import java.io.IOException; +import java.sql.SQLException; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.bind.JAXBContext; @@ -54,6 +60,12 @@ log.log(Level.SEVERE, "Unable to parse CLI options", e); } catch (InvalidOptionsException e) { log.log(Level.SEVERE, "Invalid CLI options", e); + } catch (ConfigurationException e) { + log.log(Level.SEVERE, "Configuration problem", e); + } catch (SQLException e) { + log.log(Level.SEVERE, "SQL problem", e); + } catch (FormatterException e) { + log.log(Level.SEVERE, "Formatting problem", e); } } @@ -61,7 +73,7 @@ this.options = options; } - private void process() { + private void process() throws ConfigurationException, SQLException, FormatterException { /** Show info */ if (!options.getShowInfo().isEmpty()) { InfoLister infoLister = new InfoLister(System.err, this); @@ -71,10 +83,13 @@ MODE mode = options.getMode(); switch (mode) { case QUERY_NOW: + processQueryNow(); break; case PREPARE_BATCH: + processPrepareBatch(); break; case EXECUTE_BATCH: + processExecuteBatch(); break; case JUST_SHOW_INFO: // already done above @@ -85,6 +100,28 @@ } } + private void processQueryNow() throws ConfigurationException, SQLException, FormatterException { + DatabaseDefinition dd = getConfiguration().getDatabase(options.getDatabaseName()); + if (dd == null) { + throw new ConfigurationException("Database is not configured: " + options.getDatabaseName()); + } else { + FormatterDefinition fd = configuration.getFormatter(options.getFormatterName()); + if (fd == null) { + throw new ConfigurationException("Formatter is not configured: " + options.getDatabaseName()); + } else { + DatabaseConnection c = dd.connect(); + Formatter f = fd.getInstance(new FormatterContext(options.getOutputStream())); + c.executeQuery(options.getSQLCommand(), f); + } + } + } + + private void processPrepareBatch() { + } + + private void processExecuteBatch() { + } + @Override public Configuration getConfiguration() throws ConfigurationException { if (configuration == null) { @@ -93,7 +130,7 @@ return configuration; } - private void installDefaultConfiguration() { + private void installDefaultConfiguration() throws ConfigurationException { Constants.DIR.mkdir(); if (Constants.CONFIG_FILE.exists()) { @@ -102,10 +139,9 @@ try { Functions.installResource(Constants.EXAMPLE_CONFIG_FILE, Constants.CONFIG_FILE); } catch (IOException e) { - log.log(Level.SEVERE, "Unable to write example configuration to " + Constants.CONFIG_FILE, e); + throw new ConfigurationException("Unable to write example configuration to " + Constants.CONFIG_FILE, e); } } - } private Configuration loadConfiguration() throws ConfigurationException { diff -r 04db6ccd6c48 -r 9335cf31c0f2 java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java --- a/java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java Sun Dec 22 22:02:44 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java Sun Dec 22 23:31:55 2013 +0100 @@ -19,6 +19,7 @@ import info.globalcode.sql.dk.batch.Batch; import info.globalcode.sql.dk.configuration.DatabaseDefinition; +import info.globalcode.sql.dk.formatting.ColumnsHeader; import info.globalcode.sql.dk.formatting.Formatter; import java.sql.Connection; import java.sql.DriverManager; @@ -38,7 +39,7 @@ public DatabaseConnection(DatabaseDefinition databaseDefinition) throws SQLException { this.databaseDefinition = databaseDefinition; - connection = DriverManager.getConnection(databaseDefinition.getUrl(), databaseDefinition.getName(), databaseDefinition.getPassword()); + connection = DriverManager.getConnection(databaseDefinition.getUrl(), databaseDefinition.getUserName(), databaseDefinition.getPassword()); } public void executeQuery(SQLCommand sqlCommand, Formatter formatter) throws SQLException { @@ -72,7 +73,7 @@ private void processQueryCommand(SQLCommand sqlCommand, Formatter formatter) throws SQLException { formatter.writeStartResultSet(); formatter.writeQuery(sqlCommand.getQuery()); - /** TODO: formatter.writeParameters(null); */ + formatter.writeParameters(sqlCommand.getParameters()); try (PreparedStatement ps = sqlCommand.prepareStatement(connection)) { sqlCommand.parametrize(ps); try (ResultSet rs = ps.executeQuery()) { @@ -86,7 +87,7 @@ private void processUpdateCommand(SQLCommand sqlCommand, Formatter formatter) throws SQLException { formatter.writeStartUpdatesResult(); formatter.writeQuery(sqlCommand.getQuery()); - /** TODO: formatter.writeParameters(null); */ + formatter.writeParameters(sqlCommand.getParameters()); try (PreparedStatement ps = sqlCommand.prepareStatement(connection)) { sqlCommand.parametrize(ps); int updatedRowsCount = ps.executeUpdate(); @@ -104,12 +105,18 @@ } private void processResultSet(ResultSet rs, Formatter formatter) throws SQLException { - /** TODO: formatter.writeColumnsHeader(null); */ + formatter.writeColumnsHeader(new ColumnsHeader(rs.getMetaData())); + int columnCount = rs.getMetaData().getColumnCount(); + while (rs.next()) { formatter.writeStartRow(); - /** TODO: formatter.writeColumnValue(rs.get); */ + for (int i = 1; i <= columnCount; i++) { + formatter.writeColumnValue(rs.getObject(i)); + } + formatter.writeEndRow(); } + } } diff -r 04db6ccd6c48 -r 9335cf31c0f2 java/sql-dk/src/info/globalcode/sql/dk/Functions.java --- a/java/sql-dk/src/info/globalcode/sql/dk/Functions.java Sun Dec 22 22:02:44 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/Functions.java Sun Dec 22 23:31:55 2013 +0100 @@ -26,7 +26,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Map; -import java.util.logging.Level; /** * diff -r 04db6ccd6c48 -r 9335cf31c0f2 java/sql-dk/src/info/globalcode/sql/dk/SQLCommand.java --- a/java/sql-dk/src/info/globalcode/sql/dk/SQLCommand.java Sun Dec 22 22:02:44 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/SQLCommand.java Sun Dec 22 23:31:55 2013 +0100 @@ -19,6 +19,8 @@ import java.sql.Connection; import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.List; /** * @@ -29,9 +31,16 @@ private COMMAND_TYPE commandType; private String query; - public abstract PreparedStatement prepareStatement(Connection c); + public SQLCommand(COMMAND_TYPE commandType, String query) { + this.commandType = commandType; + this.query = query; + } - public abstract void parametrize(PreparedStatement ps); + public abstract PreparedStatement prepareStatement(Connection c) throws SQLException; + + public abstract void parametrize(PreparedStatement ps) throws SQLException; + + public abstract List getParameters(); public COMMAND_TYPE getCommandType() { return commandType; diff -r 04db6ccd6c48 -r 9335cf31c0f2 java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNamed.java --- a/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNamed.java Sun Dec 22 22:02:44 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNamed.java Sun Dec 22 23:31:55 2013 +0100 @@ -19,6 +19,8 @@ import java.sql.Connection; import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.List; /** * @@ -26,13 +28,25 @@ */ public class SQLCommandNamed extends SQLCommand { + private List parameters; + + public SQLCommandNamed(COMMAND_TYPE commandType, String query, List parameters) { + super(commandType, query); + this.parameters = parameters; + } + @Override - public PreparedStatement prepareStatement(Connection c) { + public PreparedStatement prepareStatement(Connection c) throws SQLException { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override - public void parametrize(PreparedStatement ps) { + public void parametrize(PreparedStatement ps) throws SQLException { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } + + @Override + public List getParameters() { + return parameters; + } } diff -r 04db6ccd6c48 -r 9335cf31c0f2 java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNumbered.java --- a/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNumbered.java Sun Dec 22 22:02:44 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/SQLCommandNumbered.java Sun Dec 22 23:31:55 2013 +0100 @@ -17,8 +17,11 @@ */ 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; /** * @@ -26,13 +29,28 @@ */ public class SQLCommandNumbered extends SQLCommand { - @Override - public PreparedStatement prepareStatement(Connection c) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + private List parameters; + + public SQLCommandNumbered(COMMAND_TYPE commandType, String query, List parameters) { + super(commandType, query); + this.parameters = parameters; } @Override - public void parametrize(PreparedStatement ps) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public PreparedStatement prepareStatement(Connection c) throws SQLException { + return c.prepareStatement(getQuery()); + } + + @Override + public void parametrize(PreparedStatement ps) throws SQLException { + int i = 1; + for (Parameter p : notNull(parameters)) { + ps.setObject(i++, p.getValue(), p.getType()); + } + } + + @Override + public List getParameters() { + return parameters; } } diff -r 04db6ccd6c48 -r 9335cf31c0f2 java/sql-dk/src/info/globalcode/sql/dk/configuration/FormatterDefinition.java --- a/java/sql-dk/src/info/globalcode/sql/dk/configuration/FormatterDefinition.java Sun Dec 22 22:02:44 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/configuration/FormatterDefinition.java Sun Dec 22 23:31:55 2013 +0100 @@ -21,6 +21,7 @@ import info.globalcode.sql.dk.DKException; import info.globalcode.sql.dk.formatting.Formatter; import info.globalcode.sql.dk.formatting.FormatterContext; +import info.globalcode.sql.dk.formatting.FormatterException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import javax.xml.bind.annotation.XmlElement; @@ -76,7 +77,7 @@ * @return * @throws DKException */ - public Formatter getInstance(FormatterContext context) throws DKException { + public Formatter getInstance(FormatterContext context) throws FormatterException { try { Constructor constructor = Class.forName(className).getConstructor(context.getClass()); @@ -84,14 +85,14 @@ if (instance instanceof Formatter) { return (Formatter) instance; } else { - throw new DKException("Formatter " + instance + " does not implement the " + Formatter.class.getName() + " interface"); + throw new FormatterException("Formatter " + instance + " does not implement the " + Formatter.class.getName() + " interface"); } } catch (ClassNotFoundException e) { - throw new DKException("No formatter class with name: " + className, e); + throw new FormatterException("No formatter class with name: " + className, e); } catch (NoSuchMethodException e) { - throw new DKException("Formatter class with no valid constructor: " + className, e); + throw new FormatterException("Formatter class with no valid constructor: " + className, e); } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new DKException("Formatter's constructor caused an error: " + className, e); + throw new FormatterException("Formatter's constructor caused an error: " + className, e); } } } diff -r 04db6ccd6c48 -r 9335cf31c0f2 java/sql-dk/src/info/globalcode/sql/dk/formatting/AbstractFormatter.java --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/AbstractFormatter.java Sun Dec 22 22:02:44 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/AbstractFormatter.java Sun Dec 22 23:31:55 2013 +0100 @@ -110,7 +110,8 @@ */ private State popState(EnumSet expected) { try { - State superior = state.pop(); + state.pop(); + State superior = state.peek(); if (expected.contains(superior)) { return superior; } else { @@ -155,7 +156,7 @@ } @Override - public void writeParameters(List parameters) { + public void writeParameters(List parameters) { peekState(EnumSet.of(State.RESULT_SET, State.UPDATES_RESULT)); if (currentColumnsHeader != null) { @@ -242,6 +243,14 @@ return currentColumnsCount; } + protected boolean isCurrentColumnFirst() { + return currentColumnsCount == 1; + } + + protected boolean isCurrentColumnLast() { + return currentColumnsCount == currentColumnsHeader.getColumnCount(); + } + /** * @return row number, 1 = first */ diff -r 04db6ccd6c48 -r 9335cf31c0f2 java/sql-dk/src/info/globalcode/sql/dk/formatting/Formatter.java --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/Formatter.java Sun Dec 22 22:02:44 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/Formatter.java Sun Dec 22 23:31:55 2013 +0100 @@ -37,7 +37,7 @@ void writeQuery(String sql); - void writeParameters(List parameters); + void writeParameters(List parameters); void writeColumnsHeader(ColumnsHeader header); diff -r 04db6ccd6c48 -r 9335cf31c0f2 java/sql-dk/src/info/globalcode/sql/dk/formatting/FormatterException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/FormatterException.java Sun Dec 22 23:31:55 2013 +0100 @@ -0,0 +1,42 @@ +/** + * SQL-DK + * Copyright © 2013 František Kučera (frantovo.cz) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package info.globalcode.sql.dk.formatting; + +import info.globalcode.sql.dk.DKException; + +/** + * + * @author Ing. František Kučera (frantovo.cz) + */ +public class FormatterException extends DKException { + + public FormatterException() { + } + + public FormatterException(String message) { + super(message); + } + + public FormatterException(Throwable cause) { + super(cause); + } + + public FormatterException(String message, Throwable cause) { + super(message, cause); + } +} diff -r 04db6ccd6c48 -r 9335cf31c0f2 java/sql-dk/src/info/globalcode/sql/dk/formatting/TabularFormatter.java --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/TabularFormatter.java Sun Dec 22 22:02:44 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/TabularFormatter.java Sun Dec 22 23:31:55 2013 +0100 @@ -17,6 +17,8 @@ */ package info.globalcode.sql.dk.formatting; +import info.globalcode.sql.dk.ColorfulPrintWriter; + /** * * @author Ing. František Kučera (frantovo.cz) @@ -24,8 +26,28 @@ public class TabularFormatter extends AbstractFormatter { public static final String NAME = "tabular"; + private ColorfulPrintWriter out; public TabularFormatter(FormatterContext formatterContext) { super(formatterContext); + out = new ColorfulPrintWriter(formatterContext.getOutputStream()); + } + + @Override + public void writeColumnValue(Object value) { + super.writeColumnValue(value); + + if (!isCurrentColumnFirst()) { + out.print(ColorfulPrintWriter.TerminalColor.Green, " | "); + } + + out.print(ColorfulPrintWriter.TerminalColor.Cyan, String.valueOf(value)); + } + + @Override + public void writeEndRow() { + super.writeEndRow(); + out.println(); + out.flush(); } }