1.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java Thu Dec 26 11:58:14 2013 +0100
1.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/CLIOptions.java Thu Dec 26 21:18:54 2013 +0100
1.3 @@ -20,6 +20,7 @@
1.4 import static info.globalcode.sql.dk.Functions.isNotEmpty;
1.5 import static info.globalcode.sql.dk.Functions.isEmpty;
1.6 import static info.globalcode.sql.dk.Functions.equalz;
1.7 +import info.globalcode.sql.dk.InfoLister.InfoType;
1.8 import java.io.OutputStream;
1.9 import java.util.ArrayList;
1.10 import java.util.Collection;
1.11 @@ -51,20 +52,9 @@
1.12 EXECUTE_BATCH,
1.13 JUST_SHOW_INFO
1.14 }
1.15 -
1.16 - public enum INFO_TYPE {
1.17 -
1.18 - HELP,
1.19 - VERSION,
1.20 - LICENSE,
1.21 - FORMATTERS,
1.22 - TYPES,
1.23 - DATABASES,
1.24 - CONNECTION
1.25 - }
1.26 private final List<NamedParameter> namedParameters = new ArrayList<>();
1.27 private final List<Parameter> numberedParameters = new ArrayList<>();
1.28 - private final EnumSet<INFO_TYPE> showInfo = EnumSet.noneOf(INFO_TYPE.class);
1.29 + private final EnumSet<InfoType> showInfo = EnumSet.noneOf(InfoType.class);
1.30
1.31 public void validate() throws InvalidOptionsException {
1.32 InvalidOptionsException e = new InvalidOptionsException();
1.33 @@ -97,7 +87,7 @@
1.34 if (!equalz(nameSuffix, DEFAULT_NAME_SUFFIX)) {
1.35 e.addProblem(new InvalidOptionsException.OptionProblem("Do not specify name suffix if just showing info."));
1.36 }
1.37 - if (showInfo.contains(INFO_TYPE.CONNECTION) && isEmpty(databaseNameToTest, false)) {
1.38 + if (showInfo.contains(InfoType.CONNECTION) && isEmpty(databaseNameToTest, false)) {
1.39 e.addProblem(new InvalidOptionsException.OptionProblem("Please specify which database should be tested."));
1.40 }
1.41 }
1.42 @@ -215,11 +205,11 @@
1.43 this.formatterName = formatterName;
1.44 }
1.45
1.46 - public void addShowInfo(INFO_TYPE info) {
1.47 + public void addShowInfo(InfoType info) {
1.48 showInfo.add(info);
1.49 }
1.50
1.51 - public EnumSet<INFO_TYPE> getShowInfo() {
1.52 + public EnumSet<InfoType> getShowInfo() {
1.53 return showInfo;
1.54 }
1.55
2.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/CLIParser.java Thu Dec 26 11:58:14 2013 +0100
2.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/CLIParser.java Thu Dec 26 21:18:54 2013 +0100
2.3 @@ -17,6 +17,7 @@
2.4 */
2.5 package info.globalcode.sql.dk;
2.6
2.7 +import info.globalcode.sql.dk.InfoLister.InfoType;
2.8 import java.util.ArrayList;
2.9 import java.util.HashMap;
2.10 import java.util.List;
2.11 @@ -100,25 +101,25 @@
2.12 options.setFormatterName(fetchNext(args, ++i));
2.13 break;
2.14 case Tokens.INFO_HELP:
2.15 - options.addShowInfo(CLIOptions.INFO_TYPE.HELP);
2.16 + options.addShowInfo(InfoType.HELP);
2.17 break;
2.18 case Tokens.INFO_FORMATTERS:
2.19 - options.addShowInfo(CLIOptions.INFO_TYPE.FORMATTERS);
2.20 + options.addShowInfo(InfoType.FORMATTERS);
2.21 break;
2.22 case Tokens.INFO_LICENSE:
2.23 - options.addShowInfo(CLIOptions.INFO_TYPE.LICENSE);
2.24 + options.addShowInfo(InfoType.LICENSE);
2.25 break;
2.26 case Tokens.INFO_TYPES:
2.27 - options.addShowInfo(CLIOptions.INFO_TYPE.TYPES);
2.28 + options.addShowInfo(InfoType.TYPES);
2.29 break;
2.30 case Tokens.INFO_VERSION:
2.31 - options.addShowInfo(CLIOptions.INFO_TYPE.VERSION);
2.32 + options.addShowInfo(InfoType.VERSION);
2.33 break;
2.34 case Tokens.INFO_DATABASES:
2.35 - options.addShowInfo(CLIOptions.INFO_TYPE.DATABASES);
2.36 + options.addShowInfo(InfoType.DATABASES);
2.37 break;
2.38 case Tokens.INFO_CONNECTION:
2.39 - options.addShowInfo(CLIOptions.INFO_TYPE.CONNECTION);
2.40 + options.addShowInfo(InfoType.CONNECTION);
2.41 options.setDatabaseNameToTest(fetchNext(args, ++i));
2.42 break;
2.43 default:
3.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/CLIStarter.java Thu Dec 26 11:58:14 2013 +0100
3.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/CLIStarter.java Thu Dec 26 21:18:54 2013 +0100
3.3 @@ -97,8 +97,10 @@
3.4 /** Show info */
3.5 if (!options.getShowInfo().isEmpty()) {
3.6 PrintStream infoOut = mode == MODE.JUST_SHOW_INFO ? System.out : System.err;
3.7 - InfoLister infoLister = new InfoLister(infoOut, this);
3.8 - infoLister.showInfo(options);
3.9 + InfoLister infoLister = new InfoLister(infoOut, this, options);
3.10 + for (InfoLister.InfoType infoType : options.getShowInfo()) {
3.11 + infoType.showInfo(infoLister);
3.12 + }
3.13 }
3.14
3.15 switch (mode) {
4.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/InfoLister.java Thu Dec 26 11:58:14 2013 +0100
4.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/InfoLister.java Thu Dec 26 21:18:54 2013 +0100
4.3 @@ -23,14 +23,18 @@
4.4 import info.globalcode.sql.dk.configuration.DatabaseDefinition;
4.5 import info.globalcode.sql.dk.configuration.FormatterDefinition;
4.6 import static info.globalcode.sql.dk.Functions.rpad;
4.7 +import info.globalcode.sql.dk.formatting.ColumnsHeader;
4.8 +import info.globalcode.sql.dk.formatting.Formatter;
4.9 +import info.globalcode.sql.dk.formatting.FormatterContext;
4.10 +import info.globalcode.sql.dk.formatting.FormatterException;
4.11 import java.io.BufferedReader;
4.12 import java.io.InputStreamReader;
4.13 import java.io.PrintStream;
4.14 import java.sql.SQLException;
4.15 -import java.util.EnumSet;
4.16 import java.util.List;
4.17 import java.util.logging.Level;
4.18 import java.util.logging.Logger;
4.19 +import javax.sql.rowset.RowSetMetaDataImpl;
4.20
4.21 /**
4.22 * Displays info like help, version etc.
4.23 @@ -42,86 +46,67 @@
4.24 private static final Logger log = Logger.getLogger(InfoLister.class.getName());
4.25 private PrintStream out;
4.26 private ConfigurationProvider configurationProvider;
4.27 + private CLIOptions options;
4.28
4.29 - public InfoLister(PrintStream out, ConfigurationProvider configurationProvider) {
4.30 + public InfoLister(PrintStream out, ConfigurationProvider configurationProvider, CLIOptions options) {
4.31 this.out = out;
4.32 this.configurationProvider = configurationProvider;
4.33 + this.options = options;
4.34 }
4.35
4.36 - public void showInfo(CLIOptions options) throws ConfigurationException {
4.37 - EnumSet<CLIOptions.INFO_TYPE> infoTypes = options.getShowInfo();
4.38 - for (CLIOptions.INFO_TYPE infoType : infoTypes) {
4.39 - switch (infoType) {
4.40 - /**
4.41 - * TODO: implement show info
4.42 - */
4.43 - case FORMATTERS:
4.44 - for (FormatterDefinition fd : configurationProvider.getConfiguration().getBuildInFormatters()) {
4.45 - log.log(Level.INFO, "Built-in formatter: {0} implemented by class: {1}", new Object[]{rpad(fd.getName(), 16), fd.getClassName()});
4.46 - }
4.47 + public void listFormatters() throws ConfigurationException {
4.48 + for (FormatterDefinition fd : configurationProvider.getConfiguration().getBuildInFormatters()) {
4.49 + log.log(Level.INFO, "Built-in formatter: {0} implemented by class: {1}", new Object[]{rpad(fd.getName(), 16), fd.getClassName()});
4.50 + }
4.51 + List<FormatterDefinition> configuredFormatters = configurationProvider.getConfiguration().getFormatters();
4.52 + for (FormatterDefinition fd : configuredFormatters) {
4.53 + log.log(Level.INFO, "Configured formatter: {0} implemented by class: {1}", new Object[]{rpad(fd.getName(), 16), fd.getClassName()});
4.54 + }
4.55 + if (configuredFormatters.isEmpty()) {
4.56 + log.log(Level.INFO, "No other formatters are configured");
4.57 + }
4.58 + String configuredDefaultFormatter = configurationProvider.getConfiguration().getDefaultFormatter();
4.59 + if (configuredDefaultFormatter == null) {
4.60 + log.log(Level.INFO, "Built-in default formatter: {0}", Configuration.DEFAULT_FORMATTER);
4.61 + } else {
4.62 + log.log(Level.INFO, "Configured default formatter: {0}", configuredDefaultFormatter);
4.63 + }
4.64 + }
4.65
4.66 - List<FormatterDefinition> configuredFormatters = configurationProvider.getConfiguration().getFormatters();
4.67 - for (FormatterDefinition fd : configuredFormatters) {
4.68 - log.log(Level.INFO, "Configured formatter: {0} implemented by class: {1}", new Object[]{rpad(fd.getName(), 16), fd.getClassName()});
4.69 - }
4.70 - if (configuredFormatters.isEmpty()) {
4.71 - log.log(Level.INFO, "No other formatters are configured");
4.72 - }
4.73 + public void listTypes() throws FormatterException {
4.74 + }
4.75
4.76 - String configuredDefaultFormatter = configurationProvider.getConfiguration().getDefaultFormatter();
4.77 - if (configuredDefaultFormatter == null) {
4.78 - log.log(Level.INFO, "Built-in default formatter: {0}", Configuration.DEFAULT_FORMATTER);
4.79 - } else {
4.80 - log.log(Level.INFO, "Configured default formatter: {0}", configuredDefaultFormatter);
4.81 - }
4.82 - break;
4.83 - case HELP:
4.84 - printResource(Constants.HELP_FILE);
4.85 - break;
4.86 - case LICENSE:
4.87 - printResource(Constants.LICENSE_FILE);
4.88 - break;
4.89 - case TYPES:
4.90 - println("TODO: list supported types");
4.91 - break;
4.92 - case VERSION:
4.93 - printResource(Constants.VERSION_FILE);
4.94 - break;
4.95 - case DATABASES:
4.96 - final List<DatabaseDefinition> configuredDatabases = configurationProvider.getConfiguration().getDatabases();
4.97 - if (configuredDatabases.isEmpty()) {
4.98 - log.log(Level.WARNING, "No databases are configured.");
4.99 - } else {
4.100 - for (DatabaseDefinition dd : configuredDatabases) {
4.101 - log.log(Level.INFO, "Configured database: {0}", dd.getName());
4.102 - }
4.103 - }
4.104 - break;
4.105 - case CONNECTION:
4.106 - boolean connectionTestResult = false;
4.107 - String dbName = options.getDatabaseNameToTest();
4.108 - log.log(Level.FINE, "Testing connection to database: {0}", dbName);
4.109 - try {
4.110 - DatabaseDefinition dd = configurationProvider.getConfiguration().getDatabase(dbName);
4.111 - if (dd == null) {
4.112 - log.log(Level.SEVERE, "No database with this name is configured: {0}", dbName);
4.113 - } else {
4.114 - log.log(Level.FINE, "Database definition was loaded from configuration");
4.115 - DatabaseConnection dc = dd.connect();
4.116 - connectionTestResult = dc.test();
4.117 - }
4.118 - } catch (ConfigurationException | SQLException e) {
4.119 - log.log(Level.SEVERE, "Error during testing connection", e);
4.120 - }
4.121 - log.log(Level.INFO, "Connection test result: {0}", connectionTestResult ? "success" : "failure");
4.122 - break;
4.123 - default:
4.124 - throw new IllegalArgumentException("Unsupported INFO_TYPE: " + infoType);
4.125 + public void listDatabases() throws ConfigurationException {
4.126 + final List<DatabaseDefinition> configuredDatabases = configurationProvider.getConfiguration().getDatabases();
4.127 + if (configuredDatabases.isEmpty()) {
4.128 + log.log(Level.WARNING, "No databases are configured.");
4.129 + } else {
4.130 + for (DatabaseDefinition dd : configuredDatabases) {
4.131 + log.log(Level.INFO, "Configured database: {0}", dd.getName());
4.132 }
4.133 }
4.134 }
4.135
4.136 - private void printResource(String fileName) {
4.137 + public void testConnection() {
4.138 + boolean connectionTestResult = false;
4.139 + String dbName = options.getDatabaseNameToTest();
4.140 + log.log(Level.FINE, "Testing connection to database: {0}", dbName);
4.141 + try {
4.142 + DatabaseDefinition dd = configurationProvider.getConfiguration().getDatabase(dbName);
4.143 + if (dd == null) {
4.144 + log.log(Level.SEVERE, "No database with this name is configured: {0}", dbName);
4.145 + } else {
4.146 + log.log(Level.FINE, "Database definition was loaded from configuration");
4.147 + DatabaseConnection dc = dd.connect();
4.148 + connectionTestResult = dc.test();
4.149 + }
4.150 + } catch (ConfigurationException | SQLException e) {
4.151 + log.log(Level.SEVERE, "Error during testing connection", e);
4.152 + }
4.153 + log.log(Level.INFO, "Connection test result: {0}", connectionTestResult ? "success" : "failure");
4.154 + }
4.155 +
4.156 + public void printResource(String fileName) {
4.157 try (BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream(fileName)))) {
4.158 while (true) {
4.159 String line = reader.readLine();
4.160 @@ -139,4 +124,104 @@
4.161 private void println(String line) {
4.162 out.println(line);
4.163 }
4.164 +
4.165 + private void printTable(Formatter formatter, ColumnsHeader header, List<Object[]> data) throws ConfigurationException, FormatterException {
4.166 + formatter.writeStartResultSet();
4.167 + formatter.writeColumnsHeader(header);
4.168 +
4.169 + for (Object[] row : data) {
4.170 + formatter.writeStartRow();
4.171 + for (Object cell : row) {
4.172 + formatter.writeColumnValue(cell);
4.173 + }
4.174 + formatter.writeEndRow();
4.175 + }
4.176 +
4.177 + formatter.writeEndResultSet();
4.178 + }
4.179 +
4.180 + private Formatter getFormatter() throws ConfigurationException, FormatterException {
4.181 + FormatterDefinition fd = configurationProvider.getConfiguration().getFormatter(options.getFormatterName());
4.182 + FormatterContext context = new FormatterContext(out);
4.183 + return fd.getInstance(context);
4.184 + }
4.185 +
4.186 + private ColumnsHeader constructHeader(HeaderField... fields) throws FormatterException {
4.187 + try {
4.188 + RowSetMetaDataImpl metaData = new RowSetMetaDataImpl();
4.189 + metaData.setColumnCount(fields.length);
4.190 +
4.191 + for (int i = 0; i < fields.length; i++) {
4.192 + HeaderField hf = fields[i];
4.193 + int sqlIndex = i + 1;
4.194 + metaData.setColumnName(sqlIndex, hf.name);
4.195 + metaData.setColumnLabel(sqlIndex, hf.name);
4.196 + metaData.setColumnType(sqlIndex, hf.type.getCode());
4.197 + metaData.setColumnTypeName(sqlIndex, hf.type.name());
4.198 + }
4.199 +
4.200 + return new ColumnsHeader(metaData);
4.201 + } catch (SQLException e) {
4.202 + throw new FormatterException("Error while constructing table headers", e);
4.203 + }
4.204 + }
4.205 +
4.206 + private static class HeaderField {
4.207 +
4.208 + String name;
4.209 + SQLType type;
4.210 +
4.211 + public HeaderField(String name, SQLType type) {
4.212 + this.name = name;
4.213 + this.type = type;
4.214 + }
4.215 + }
4.216 +
4.217 + public enum InfoType {
4.218 +
4.219 + HELP {
4.220 + @Override
4.221 + public void showInfo(InfoLister infoLister) {
4.222 + infoLister.printResource(Constants.HELP_FILE);
4.223 + }
4.224 + },
4.225 + VERSION {
4.226 + @Override
4.227 + public void showInfo(InfoLister infoLister) {
4.228 + infoLister.printResource(Constants.VERSION_FILE);
4.229 + }
4.230 + },
4.231 + LICENSE {
4.232 + @Override
4.233 + public void showInfo(InfoLister infoLister) {
4.234 + infoLister.printResource(Constants.LICENSE_FILE);
4.235 + }
4.236 + },
4.237 + FORMATTERS {
4.238 + @Override
4.239 + public void showInfo(InfoLister infoLister) throws ConfigurationException {
4.240 + infoLister.listFormatters();
4.241 + }
4.242 + },
4.243 + TYPES {
4.244 + @Override
4.245 + public void showInfo(InfoLister infoLister) throws FormatterException {
4.246 + infoLister.listTypes();
4.247 + }
4.248 + },
4.249 + DATABASES {
4.250 + @Override
4.251 + public void showInfo(InfoLister infoLister) throws ConfigurationException {
4.252 + infoLister.listDatabases();
4.253 + }
4.254 + },
4.255 + CONNECTION {
4.256 + @Override
4.257 + public void showInfo(InfoLister infoLister) {
4.258 + infoLister.testConnection();
4.259 + }
4.260 + };
4.261 +
4.262 + public abstract void showInfo(InfoLister infoLister) throws ConfigurationException, FormatterException;
4.263 + }
4.264 }
5.1 --- a/java/sql-dk/test/info/globalcode/sql/dk/CLIParserTest.java Thu Dec 26 11:58:14 2013 +0100
5.2 +++ b/java/sql-dk/test/info/globalcode/sql/dk/CLIParserTest.java Thu Dec 26 21:18:54 2013 +0100
5.3 @@ -184,6 +184,6 @@
5.4
5.5 assertEquals(options.getMode(), CLIOptions.MODE.JUST_SHOW_INFO);
5.6 assertEquals(options.getShowInfo().size(), 1);
5.7 - assertTrue(options.getShowInfo().contains(CLIOptions.INFO_TYPE.HELP));
5.8 + assertTrue(options.getShowInfo().contains(CLIOptions.InfoType.HELP));
5.9 }
5.10 }
5.11 \ No newline at end of file