# HG changeset patch # User František Kučera # Date 1387732778 -3600 # Node ID d66858b4b5636b448c00a517f727ed33a259de7a # Parent 57c44a6baedb12dcd8ec51aefc7e5fb0b3da5361 more configuration, more JAXB, more formatters diff -r 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java --- a/java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java Sat Dec 21 22:22:30 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java Sun Dec 22 18:19:38 2013 +0100 @@ -20,6 +20,7 @@ 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.util.ArrayList; import java.util.Collection; import java.util.EnumSet; @@ -57,14 +58,6 @@ DATABASES, CONNECTION } - - public enum COMMAND_TYPE { - - /** SELECT */ - QUERY, - /** INSERT, UPDATE, DELETE */ - UPDATE - }; private COMMAND_TYPE commandType; private final Collection namedParameters = new ArrayList<>(); private final List numberedParameters = new ArrayList<>(); diff -r 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/CLIParser.java --- a/java/sql-dk/src/info/globalcode/sql/dk/CLIParser.java Sat Dec 21 22:22:30 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/CLIParser.java Sun Dec 22 18:19:38 2013 +0100 @@ -17,6 +17,7 @@ */ 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; @@ -75,12 +76,12 @@ break; case Tokens.SQL: options.setSql(fetchNext(args, ++i)); - options.setCommandType(CLIOptions.COMMAND_TYPE.QUERY); + options.setCommandType(COMMAND_TYPE.QUERY); break; case Tokens.SQL_UPDATE: case Tokens.SQL_INSERT: options.setSql(fetchNext(args, ++i)); - options.setCommandType(CLIOptions.COMMAND_TYPE.UPDATE); + options.setCommandType(COMMAND_TYPE.UPDATE); break; case Tokens.BATCH: options.setBatch(true); diff -r 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/Constants.java --- a/java/sql-dk/src/info/globalcode/sql/dk/Constants.java Sat Dec 21 22:22:30 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/Constants.java Sun Dec 22 18:19:38 2013 +0100 @@ -27,6 +27,7 @@ public static final String LICENSE_FILE = "info/globalcode/sql/dk/license.txt"; public static final String VERSION_FILE = "info/globalcode/sql/dk/version.txt"; public static final String HELP_FILE = "info/globalcode/sql/dk/help.txt"; + public static final String XMLNS_CONFIGURATION = "https://sql-dk.globalcode.info/xmlns/configuration"; private Constants() { } diff -r 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java --- a/java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java Sat Dec 21 22:22:30 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java Sun Dec 22 18:19:38 2013 +0100 @@ -17,9 +17,13 @@ */ package info.globalcode.sql.dk; +import info.globalcode.sql.dk.batch.Batch; import info.globalcode.sql.dk.configuration.DatabaseDefinition; +import info.globalcode.sql.dk.formatting.Formatter; import java.sql.Connection; import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; /** @@ -36,4 +40,76 @@ connection = DriverManager.getConnection(databaseDefinition.getUrl(), databaseDefinition.getName(), databaseDefinition.getPassword()); } + + public void executeQuery(SQLCommand sqlCommand, Formatter formatter) throws SQLException { + formatter.writeStartDatabase(databaseDefinition); + processCommand(sqlCommand, formatter); + formatter.writeEndDatabase(); + } + + public void executeBatch(Batch batch, Formatter formatter) throws SQLException { + formatter.writeStartDatabase(databaseDefinition); + while (batch.hasNext()) { + processCommand(batch.next(), formatter); + } + formatter.writeEndDatabase(); + } + + 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()); + /** TODO: formatter.writeParameters(null); */ + try (PreparedStatement ps = sqlCommand.prepareStatement(connection)) { + sqlCommand.parametrize(ps); + try (ResultSet rs = ps.executeQuery()) { + processResultSet(rs, formatter); + } + } + + formatter.writeEndResultSet(); + } + + private void processUpdateCommand(SQLCommand sqlCommand, Formatter formatter) throws SQLException { + formatter.writeStartUpdatesResult(); + formatter.writeQuery(sqlCommand.getQuery()); + /** TODO: formatter.writeParameters(null); */ + 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 { + /** TODO: formatter.writeColumnsHeader(null); */ + while (rs.next()) { + formatter.writeStartRow(); + + /** TODO: formatter.writeColumnValue(rs.get); */ + formatter.writeEndRow(); + } + } } diff -r 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/Functions.java --- a/java/sql-dk/src/info/globalcode/sql/dk/Functions.java Sat Dec 21 22:22:30 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/Functions.java Sun Dec 22 18:19:38 2013 +0100 @@ -17,6 +17,7 @@ */ package info.globalcode.sql.dk; +import info.globalcode.sql.dk.configuration.NameIdentified; import java.util.ArrayList; import java.util.Collection; import java.util.Map; @@ -84,4 +85,14 @@ return c; } } + + public static T findByName(Collection collection, String name) { + for (T element : collection) { + if (equalz(element.getName(), name)) { + return element; + } + } + + return null; + } } diff -r 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/SQLCommand.java --- a/java/sql-dk/src/info/globalcode/sql/dk/SQLCommand.java Sat Dec 21 22:22:30 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/SQLCommand.java Sun Dec 22 18:19:38 2013 +0100 @@ -26,9 +26,30 @@ */ public abstract class SQLCommand { + private COMMAND_TYPE commandType; private String query; public abstract PreparedStatement prepareStatement(Connection c); public abstract void parametrize(PreparedStatement ps); + + 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 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/batch/Batch.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/sql-dk/src/info/globalcode/sql/dk/batch/Batch.java Sun Dec 22 18:19:38 2013 +0100 @@ -0,0 +1,46 @@ +/** + * 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.batch; + +import info.globalcode.sql.dk.SQLCommand; +import java.util.Iterator; + +/** + * + * @author Ing. František Kučera (frantovo.cz) + */ +public class Batch implements Iterator { + + @Override + public boolean hasNext() { + /** TODO: implement iterator */ + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public SQLCommand next() { + /** TODO: implement iterator */ + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public void remove() { + /** TODO: implement iterator */ + throw new UnsupportedOperationException("Not supported yet."); + } +} diff -r 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/configuration/Configuration.java --- a/java/sql-dk/src/info/globalcode/sql/dk/configuration/Configuration.java Sat Dec 21 22:22:30 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/configuration/Configuration.java Sun Dec 22 18:19:38 2013 +0100 @@ -17,20 +17,40 @@ */ package info.globalcode.sql.dk.configuration; +import static info.globalcode.sql.dk.Constants.XMLNS_CONFIGURATION; +import static info.globalcode.sql.dk.Functions.findByName; +import info.globalcode.sql.dk.formatting.SilentFormatter; +import info.globalcode.sql.dk.formatting.XmlFormatter; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; +import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; /** * * @author Ing. František Kučera (frantovo.cz) */ -@XmlRootElement +@XmlRootElement(name = "configuration", namespace = XMLNS_CONFIGURATION) public class Configuration { private List databases = new ArrayList<>(); private List formatters = new ArrayList<>(); + private String defaultFormatter; + /** + * Default list of formatters. Is used if particular name is not found in user configuration. + */ + private static final Collection buildInFormatters; + static { + Collection l = new ArrayList<>(); + l.add(new FormatterDefinition(SilentFormatter.NAME, SilentFormatter.class.getName())); + l.add(new FormatterDefinition(XmlFormatter.NAME, XmlFormatter.class.getName())); + buildInFormatters = Collections.unmodifiableCollection(l); + } + + @XmlElement(name = "database", namespace = XMLNS_CONFIGURATION) public List getDatabases() { return databases; } @@ -39,6 +59,11 @@ this.databases = databases; } + public DatabaseDefinition getDatabase(String name) { + return findByName(databases, name); + } + + @XmlElement(name = "formatter", namespace = XMLNS_CONFIGURATION) public List getFormatters() { return formatters; } @@ -46,4 +71,21 @@ public void setFormatters(List formatters) { this.formatters = formatters; } + + public FormatterDefinition getFormatter(String name) { + FormatterDefinition fd = findByName(formatters, name); + return fd == null ? findByName(buildInFormatters, name) : fd; + } + + /** + * @return name of default formatter, is used if name is not specified on CLI + */ + @XmlElement(name = "defaultFormatter", namespace = XMLNS_CONFIGURATION) + public String getDefaultFormatter() { + return defaultFormatter; + } + + public void setDefaultFormatter(String defaultFormatter) { + this.defaultFormatter = defaultFormatter; + } } diff -r 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/configuration/DatabaseDefinition.java --- a/java/sql-dk/src/info/globalcode/sql/dk/configuration/DatabaseDefinition.java Sat Dec 21 22:22:30 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/configuration/DatabaseDefinition.java Sun Dec 22 18:19:38 2013 +0100 @@ -17,9 +17,10 @@ */ package info.globalcode.sql.dk.configuration; +import static info.globalcode.sql.dk.Constants.XMLNS_CONFIGURATION; import info.globalcode.sql.dk.DatabaseConnection; +import java.sql.SQLException; import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlTransient; /** * @@ -32,7 +33,7 @@ private String userName; private String password; - @XmlElement(name = "name") + @XmlElement(name = "name", namespace = XMLNS_CONFIGURATION) @Override public String getName() { return name; @@ -42,7 +43,7 @@ this.name = name; } - @XmlElement(name = "url") + @XmlElement(name = "url", namespace = XMLNS_CONFIGURATION) public String getUrl() { return url; } @@ -51,7 +52,7 @@ this.url = url; } - @XmlElement(name = "userName") + @XmlElement(name = "userName", namespace = XMLNS_CONFIGURATION) public String getUserName() { return userName; } @@ -60,7 +61,7 @@ this.userName = userName; } - @XmlElement(name = "password") + @XmlElement(name = "password", namespace = XMLNS_CONFIGURATION) public String getPassword() { return password; } @@ -69,8 +70,7 @@ this.password = password; } - @XmlTransient - public DatabaseConnection connect() { + public DatabaseConnection connect() throws SQLException { return new DatabaseConnection(this); } } diff -r 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/configuration/FormatterDefinition.java --- a/java/sql-dk/src/info/globalcode/sql/dk/configuration/FormatterDefinition.java Sat Dec 21 22:22:30 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/configuration/FormatterDefinition.java Sun Dec 22 18:19:38 2013 +0100 @@ -17,13 +17,13 @@ */ package info.globalcode.sql.dk.configuration; +import static info.globalcode.sql.dk.Constants.XMLNS_CONFIGURATION; import info.globalcode.sql.dk.DKException; import info.globalcode.sql.dk.formatting.Formatter; import info.globalcode.sql.dk.formatting.FormatterContext; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlTransient; /** * @@ -34,7 +34,15 @@ private String name; private String className; - @XmlElement(name = "name") + public FormatterDefinition() { + } + + public FormatterDefinition(String name, String className) { + this.name = name; + this.className = className; + } + + @XmlElement(name = "name", namespace = XMLNS_CONFIGURATION) @Override public String getName() { return name; @@ -54,7 +62,7 @@ * * @return fully qualified class name */ - @XmlElement(name = "class") + @XmlElement(name = "class", namespace = XMLNS_CONFIGURATION) public String getClassName() { return className; } @@ -68,7 +76,6 @@ * @return * @throws DKException */ - @XmlTransient public Formatter getInstance(FormatterContext context) throws DKException { try { Constructor constructor = Class.forName(className).getConstructor(context.getClass()); diff -r 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/formatting/AbstractFormatter.java --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/AbstractFormatter.java Sat Dec 21 22:22:30 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/AbstractFormatter.java Sun Dec 22 18:19:38 2013 +0100 @@ -18,6 +18,7 @@ package info.globalcode.sql.dk.formatting; import info.globalcode.sql.dk.Parameter; +import info.globalcode.sql.dk.configuration.DatabaseDefinition; import java.util.EmptyStackException; import java.util.EnumSet; import java.util.List; @@ -121,7 +122,7 @@ } @Override - public void writeStartDatabase() { + public void writeStartDatabase(DatabaseDefinition databaseDefinition) { pushState(State.DATABASE, EnumSet.of(State.ROOT)); } diff -r 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/formatting/Formatter.java --- a/java/sql-dk/src/info/globalcode/sql/dk/formatting/Formatter.java Sat Dec 21 22:22:30 2013 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/Formatter.java Sun Dec 22 18:19:38 2013 +0100 @@ -18,6 +18,7 @@ package info.globalcode.sql.dk.formatting; import info.globalcode.sql.dk.Parameter; +import info.globalcode.sql.dk.configuration.DatabaseDefinition; import java.util.List; /** @@ -26,7 +27,7 @@ */ public interface Formatter { - void writeStartDatabase(); + void writeStartDatabase(DatabaseDefinition databaseDefinition); void writeEndDatabase(); diff -r 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/formatting/SilentFormatter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/SilentFormatter.java Sun Dec 22 18:19:38 2013 +0100 @@ -0,0 +1,33 @@ +/** + * 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; + +/** + * Does not output anything, can be used instead of + * /dev/null. + * + * @author Ing. František Kučera (frantovo.cz) + */ +public class SilentFormatter extends AbstractFormatter { + + public static final String NAME = "silent"; + + public SilentFormatter(FormatterContext formatterContext) { + super(formatterContext); + } +} diff -r 57c44a6baedb -r d66858b4b563 java/sql-dk/src/info/globalcode/sql/dk/formatting/XmlFormatter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/java/sql-dk/src/info/globalcode/sql/dk/formatting/XmlFormatter.java Sun Dec 22 18:19:38 2013 +0100 @@ -0,0 +1,31 @@ +/** + * 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; + +/** + * + * @author Ing. František Kučera (frantovo.cz) + */ +public class XmlFormatter extends AbstractFormatter { + + public static final String NAME = "xml"; + + public XmlFormatter(FormatterContext formatterContext) { + super(formatterContext); + } +}