java/sql-dk/src/info/globalcode/sql/dk/InfoLister.java
branchv_0
changeset 159 9632b23df30c
parent 158 770b5009ec42
child 160 84ea4a819fb2
     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 {