diff -r 770b5009ec42 -r 9632b23df30c java/sql-dk/src/info/globalcode/sql/dk/InfoLister.java --- a/java/sql-dk/src/info/globalcode/sql/dk/InfoLister.java Wed Jan 15 18:15:55 2014 +0100 +++ b/java/sql-dk/src/info/globalcode/sql/dk/InfoLister.java Wed Jan 15 21:06:12 2014 +0100 @@ -22,19 +22,25 @@ import info.globalcode.sql.dk.configuration.ConfigurationProvider; import info.globalcode.sql.dk.configuration.DatabaseDefinition; import info.globalcode.sql.dk.configuration.FormatterDefinition; +import info.globalcode.sql.dk.configuration.Property; import info.globalcode.sql.dk.formatting.ColumnsHeader; +import info.globalcode.sql.dk.formatting.FakeSqlArray; import info.globalcode.sql.dk.formatting.Formatter; import info.globalcode.sql.dk.formatting.FormatterContext; import info.globalcode.sql.dk.formatting.FormatterException; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintStream; +import java.sql.Array; import java.sql.Driver; +import java.sql.DriverPropertyInfo; import java.sql.SQLException; import java.util.ArrayList; import java.util.EnumSet; +import java.util.HashSet; import java.util.List; import java.util.ServiceLoader; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.sql.rowset.RowSetMetaDataImpl; @@ -47,6 +53,10 @@ public class InfoLister { private static final Logger log = Logger.getLogger(InfoLister.class.getName()); + /** + * Fake database name for output formatting + */ + public static final String CONFIG_DB_NAME = "sqldk_configuration"; private PrintStream out; private ConfigurationProvider configurationProvider; private CLIOptions options; @@ -67,6 +77,7 @@ switch (infoType) { case CONNECTION: case JDBC_DRIVERS: + case JDBC_PROPERTIES: case DATABASES: case FORMATTERS: case TYPES: @@ -79,10 +90,10 @@ try (Formatter f = getFormatter()) { formatter = f; formatter.writeStartBatch(); - formatter.writeStartDatabase(new DatabaseDefinition()); - formatter.writeStartStatement(); + DatabaseDefinition dd = new DatabaseDefinition(); + dd.setName(CONFIG_DB_NAME); + formatter.writeStartDatabase(dd); showInfos(commands); - formatter.writeEndStatement(); formatter.writeEndDatabase(); formatter.writeEndBatch(); formatter.close(); @@ -117,7 +128,7 @@ data.add(new Object[]{fd.getName(), false, defaultFormatter.equals(fd.getName()), fd.getClassName()}); } - printTable(formatter, header, data); + printTable(formatter, header, data, "-- configured and built-in output formatters", null); } @@ -128,7 +139,7 @@ for (SQLType sqlType : SQLType.values()) { data.add(new Object[]{sqlType.name(), sqlType.getCode()}); } - printTable(formatter, header, data); + printTable(formatter, header, data, "-- data types", null); log.log(Level.INFO, "Type names in --types option are case insensitive"); } @@ -148,7 +159,7 @@ } } - printTable(formatter, header, data); + printTable(formatter, header, data, "-- configured databases", null); } public void listJdbcDrivers() throws FormatterException, ConfigurationException { @@ -167,11 +178,90 @@ d.getMajorVersion() + "." + d.getMinorVersion(), d.getMajorVersion(), d.getMinorVersion(), - d.jdbcCompliant()}); + d.jdbcCompliant() + }); } - printTable(formatter, header, data); + printTable(formatter, header, data, "-- discovered JDBC drivers (available on the CLASSPATH)", null); + } + public void listJdbcProperties() throws FormatterException, ConfigurationException { + for (String dbName : options.getDatabaseNamesToListProperties()) { + ColumnsHeader header = constructHeader( + new HeaderField("property_name", SQLType.VARCHAR), + new HeaderField("required", SQLType.BOOLEAN), + new HeaderField("choices", SQLType.ARRAY), + new HeaderField("configured_value", SQLType.VARCHAR), + new HeaderField("description", SQLType.VARCHAR)); + List data = new ArrayList<>(); + + DatabaseDefinition dd = configurationProvider.getConfiguration().getDatabase(dbName); + + Driver driver = findDriver(dd); + + if (driver == null) { + log.log(Level.WARNING, "No JDBC driver was found for DB: {0} with URL: {1}", new Object[]{dd.getName(), dd.getUrl()}); + } else { + log.log(Level.INFO, "For DB: {0} was found JDBC driver: {1}", new Object[]{dd.getName(), driver.getClass().getName()}); + + try { + DriverPropertyInfo[] propertyInfos = driver.getPropertyInfo(dd.getUrl(), dd.getProperties().getJavaProperties()); + + Set standardProperties = new HashSet<>(); + + for (DriverPropertyInfo pi : propertyInfos) { + Array choices = new FakeSqlArray(pi.choices, SQLType.VARCHAR); + data.add(new Object[]{ + pi.name, + pi.required, + choices.getArray() == null ? "" : choices, + pi.value == null ? "" : pi.value, + pi.description + }); + standardProperties.add(pi.name); + } + + for (Property p : dd.getProperties()) { + if (!standardProperties.contains(p.getName())) { + data.add(new Object[]{ + p.getName(), + "", + "", + p.getValue(), + "" + }); + log.log(Level.WARNING, "Your configuration contains property „{0}“ not declared by the JDBC driver.", p.getName()); + } + } + + } catch (SQLException e) { + log.log(Level.WARNING, "Error during getting property infos.", e); + } + + List parameters = new ArrayList<>(); + parameters.add(new NamedParameter("databgase", dbName, SQLType.VARCHAR)); + parameters.add(new NamedParameter("driver_class", driver.getClass().getName(), SQLType.VARCHAR)); + parameters.add(new NamedParameter("driver_major_version", driver.getMajorVersion(), SQLType.INTEGER)); + parameters.add(new NamedParameter("driver_minor_version", driver.getMinorVersion(), SQLType.INTEGER)); + + printTable(formatter, header, data, "-- configured and configurable JDBC driver properties", parameters); + } + } + + } + + private Driver findDriver(DatabaseDefinition dd) { + final ServiceLoader drivers = ServiceLoader.load(Driver.class); + for (Driver d : drivers) { + try { + if (d.acceptsURL(dd.getUrl())) { + return d; + } + } catch (SQLException e) { + log.log(Level.WARNING, "Error during finding JDBC driver for: " + dd.getName(), e); + } + } + return null; } public void testConnection() throws FormatterException, ConfigurationException { @@ -185,7 +275,7 @@ data.add(testConnection(dbName)); } - printTable(formatter, header, data); + printTable(formatter, header, data, "-- database configuration and connectivity test", null); } public Object[] testConnection(String dbName) { @@ -228,7 +318,16 @@ out.println(line); } - private void printTable(Formatter formatter, ColumnsHeader header, List data) throws ConfigurationException, FormatterException { + private void printTable(Formatter formatter, ColumnsHeader header, List data, String sql, List parameters) throws ConfigurationException, FormatterException { + formatter.writeStartStatement(); + + if (sql != null) { + formatter.writeQuery(sql); + if (parameters != null) { + formatter.writeParameters(parameters); + } + } + formatter.writeStartResultSet(header); for (Object[] row : data) { @@ -240,6 +339,7 @@ } formatter.writeEndResultSet(); + formatter.writeEndStatement(); } private Formatter getFormatter() throws ConfigurationException, FormatterException { @@ -319,6 +419,12 @@ infoLister.listJdbcDrivers(); } }, + JDBC_PROPERTIES { + @Override + public void showInfo(InfoLister infoLister) throws ConfigurationException, FormatterException { + infoLister.listJdbcProperties(); + } + }, DATABASES { @Override public void showInfo(InfoLister infoLister) throws FormatterException, ConfigurationException {