java/sql-dk/src/info/globalcode/sql/dk/InfoLister.java
branchv_0
changeset 159 9632b23df30c
parent 158 770b5009ec42
child 160 84ea4a819fb2
--- 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<Object[]> 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<String> 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<Parameter> 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<Driver> 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<Object[]> data) throws ConfigurationException, FormatterException {
+	private void printTable(Formatter formatter, ColumnsHeader header, List<Object[]> data, String sql, List<Parameter> 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 {