1.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/InfoLister.java Wed Jan 15 18:15:55 2014 +0100
1.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/InfoLister.java Wed Jan 15 21:06:12 2014 +0100
1.3 @@ -22,19 +22,25 @@
1.4 import info.globalcode.sql.dk.configuration.ConfigurationProvider;
1.5 import info.globalcode.sql.dk.configuration.DatabaseDefinition;
1.6 import info.globalcode.sql.dk.configuration.FormatterDefinition;
1.7 +import info.globalcode.sql.dk.configuration.Property;
1.8 import info.globalcode.sql.dk.formatting.ColumnsHeader;
1.9 +import info.globalcode.sql.dk.formatting.FakeSqlArray;
1.10 import info.globalcode.sql.dk.formatting.Formatter;
1.11 import info.globalcode.sql.dk.formatting.FormatterContext;
1.12 import info.globalcode.sql.dk.formatting.FormatterException;
1.13 import java.io.BufferedReader;
1.14 import java.io.InputStreamReader;
1.15 import java.io.PrintStream;
1.16 +import java.sql.Array;
1.17 import java.sql.Driver;
1.18 +import java.sql.DriverPropertyInfo;
1.19 import java.sql.SQLException;
1.20 import java.util.ArrayList;
1.21 import java.util.EnumSet;
1.22 +import java.util.HashSet;
1.23 import java.util.List;
1.24 import java.util.ServiceLoader;
1.25 +import java.util.Set;
1.26 import java.util.logging.Level;
1.27 import java.util.logging.Logger;
1.28 import javax.sql.rowset.RowSetMetaDataImpl;
1.29 @@ -47,6 +53,10 @@
1.30 public class InfoLister {
1.31
1.32 private static final Logger log = Logger.getLogger(InfoLister.class.getName());
1.33 + /**
1.34 + * Fake database name for output formatting
1.35 + */
1.36 + public static final String CONFIG_DB_NAME = "sqldk_configuration";
1.37 private PrintStream out;
1.38 private ConfigurationProvider configurationProvider;
1.39 private CLIOptions options;
1.40 @@ -67,6 +77,7 @@
1.41 switch (infoType) {
1.42 case CONNECTION:
1.43 case JDBC_DRIVERS:
1.44 + case JDBC_PROPERTIES:
1.45 case DATABASES:
1.46 case FORMATTERS:
1.47 case TYPES:
1.48 @@ -79,10 +90,10 @@
1.49 try (Formatter f = getFormatter()) {
1.50 formatter = f;
1.51 formatter.writeStartBatch();
1.52 - formatter.writeStartDatabase(new DatabaseDefinition());
1.53 - formatter.writeStartStatement();
1.54 + DatabaseDefinition dd = new DatabaseDefinition();
1.55 + dd.setName(CONFIG_DB_NAME);
1.56 + formatter.writeStartDatabase(dd);
1.57 showInfos(commands);
1.58 - formatter.writeEndStatement();
1.59 formatter.writeEndDatabase();
1.60 formatter.writeEndBatch();
1.61 formatter.close();
1.62 @@ -117,7 +128,7 @@
1.63 data.add(new Object[]{fd.getName(), false, defaultFormatter.equals(fd.getName()), fd.getClassName()});
1.64 }
1.65
1.66 - printTable(formatter, header, data);
1.67 + printTable(formatter, header, data, "-- configured and built-in output formatters", null);
1.68
1.69
1.70 }
1.71 @@ -128,7 +139,7 @@
1.72 for (SQLType sqlType : SQLType.values()) {
1.73 data.add(new Object[]{sqlType.name(), sqlType.getCode()});
1.74 }
1.75 - printTable(formatter, header, data);
1.76 + printTable(formatter, header, data, "-- data types", null);
1.77 log.log(Level.INFO, "Type names in --types option are case insensitive");
1.78 }
1.79
1.80 @@ -148,7 +159,7 @@
1.81 }
1.82 }
1.83
1.84 - printTable(formatter, header, data);
1.85 + printTable(formatter, header, data, "-- configured databases", null);
1.86 }
1.87
1.88 public void listJdbcDrivers() throws FormatterException, ConfigurationException {
1.89 @@ -167,11 +178,90 @@
1.90 d.getMajorVersion() + "." + d.getMinorVersion(),
1.91 d.getMajorVersion(),
1.92 d.getMinorVersion(),
1.93 - d.jdbcCompliant()});
1.94 + d.jdbcCompliant()
1.95 + });
1.96 }
1.97
1.98 - printTable(formatter, header, data);
1.99 + printTable(formatter, header, data, "-- discovered JDBC drivers (available on the CLASSPATH)", null);
1.100 + }
1.101
1.102 + public void listJdbcProperties() throws FormatterException, ConfigurationException {
1.103 + for (String dbName : options.getDatabaseNamesToListProperties()) {
1.104 + ColumnsHeader header = constructHeader(
1.105 + new HeaderField("property_name", SQLType.VARCHAR),
1.106 + new HeaderField("required", SQLType.BOOLEAN),
1.107 + new HeaderField("choices", SQLType.ARRAY),
1.108 + new HeaderField("configured_value", SQLType.VARCHAR),
1.109 + new HeaderField("description", SQLType.VARCHAR));
1.110 + List<Object[]> data = new ArrayList<>();
1.111 +
1.112 + DatabaseDefinition dd = configurationProvider.getConfiguration().getDatabase(dbName);
1.113 +
1.114 + Driver driver = findDriver(dd);
1.115 +
1.116 + if (driver == null) {
1.117 + log.log(Level.WARNING, "No JDBC driver was found for DB: {0} with URL: {1}", new Object[]{dd.getName(), dd.getUrl()});
1.118 + } else {
1.119 + log.log(Level.INFO, "For DB: {0} was found JDBC driver: {1}", new Object[]{dd.getName(), driver.getClass().getName()});
1.120 +
1.121 + try {
1.122 + DriverPropertyInfo[] propertyInfos = driver.getPropertyInfo(dd.getUrl(), dd.getProperties().getJavaProperties());
1.123 +
1.124 + Set<String> standardProperties = new HashSet<>();
1.125 +
1.126 + for (DriverPropertyInfo pi : propertyInfos) {
1.127 + Array choices = new FakeSqlArray(pi.choices, SQLType.VARCHAR);
1.128 + data.add(new Object[]{
1.129 + pi.name,
1.130 + pi.required,
1.131 + choices.getArray() == null ? "" : choices,
1.132 + pi.value == null ? "" : pi.value,
1.133 + pi.description
1.134 + });
1.135 + standardProperties.add(pi.name);
1.136 + }
1.137 +
1.138 + for (Property p : dd.getProperties()) {
1.139 + if (!standardProperties.contains(p.getName())) {
1.140 + data.add(new Object[]{
1.141 + p.getName(),
1.142 + "",
1.143 + "",
1.144 + p.getValue(),
1.145 + ""
1.146 + });
1.147 + log.log(Level.WARNING, "Your configuration contains property „{0}“ not declared by the JDBC driver.", p.getName());
1.148 + }
1.149 + }
1.150 +
1.151 + } catch (SQLException e) {
1.152 + log.log(Level.WARNING, "Error during getting property infos.", e);
1.153 + }
1.154 +
1.155 + List<Parameter> parameters = new ArrayList<>();
1.156 + parameters.add(new NamedParameter("databgase", dbName, SQLType.VARCHAR));
1.157 + parameters.add(new NamedParameter("driver_class", driver.getClass().getName(), SQLType.VARCHAR));
1.158 + parameters.add(new NamedParameter("driver_major_version", driver.getMajorVersion(), SQLType.INTEGER));
1.159 + parameters.add(new NamedParameter("driver_minor_version", driver.getMinorVersion(), SQLType.INTEGER));
1.160 +
1.161 + printTable(formatter, header, data, "-- configured and configurable JDBC driver properties", parameters);
1.162 + }
1.163 + }
1.164 +
1.165 + }
1.166 +
1.167 + private Driver findDriver(DatabaseDefinition dd) {
1.168 + final ServiceLoader<Driver> drivers = ServiceLoader.load(Driver.class);
1.169 + for (Driver d : drivers) {
1.170 + try {
1.171 + if (d.acceptsURL(dd.getUrl())) {
1.172 + return d;
1.173 + }
1.174 + } catch (SQLException e) {
1.175 + log.log(Level.WARNING, "Error during finding JDBC driver for: " + dd.getName(), e);
1.176 + }
1.177 + }
1.178 + return null;
1.179 }
1.180
1.181 public void testConnection() throws FormatterException, ConfigurationException {
1.182 @@ -185,7 +275,7 @@
1.183 data.add(testConnection(dbName));
1.184 }
1.185
1.186 - printTable(formatter, header, data);
1.187 + printTable(formatter, header, data, "-- database configuration and connectivity test", null);
1.188 }
1.189
1.190 public Object[] testConnection(String dbName) {
1.191 @@ -228,7 +318,16 @@
1.192 out.println(line);
1.193 }
1.194
1.195 - private void printTable(Formatter formatter, ColumnsHeader header, List<Object[]> data) throws ConfigurationException, FormatterException {
1.196 + private void printTable(Formatter formatter, ColumnsHeader header, List<Object[]> data, String sql, List<Parameter> parameters) throws ConfigurationException, FormatterException {
1.197 + formatter.writeStartStatement();
1.198 +
1.199 + if (sql != null) {
1.200 + formatter.writeQuery(sql);
1.201 + if (parameters != null) {
1.202 + formatter.writeParameters(parameters);
1.203 + }
1.204 + }
1.205 +
1.206 formatter.writeStartResultSet(header);
1.207
1.208 for (Object[] row : data) {
1.209 @@ -240,6 +339,7 @@
1.210 }
1.211
1.212 formatter.writeEndResultSet();
1.213 + formatter.writeEndStatement();
1.214 }
1.215
1.216 private Formatter getFormatter() throws ConfigurationException, FormatterException {
1.217 @@ -319,6 +419,12 @@
1.218 infoLister.listJdbcDrivers();
1.219 }
1.220 },
1.221 + JDBC_PROPERTIES {
1.222 + @Override
1.223 + public void showInfo(InfoLister infoLister) throws ConfigurationException, FormatterException {
1.224 + infoLister.listJdbcProperties();
1.225 + }
1.226 + },
1.227 DATABASES {
1.228 @Override
1.229 public void showInfo(InfoLister infoLister) throws FormatterException, ConfigurationException {