20 import info.globalcode.sql.dk.configuration.Configuration; |
20 import info.globalcode.sql.dk.configuration.Configuration; |
21 import info.globalcode.sql.dk.configuration.ConfigurationException; |
21 import info.globalcode.sql.dk.configuration.ConfigurationException; |
22 import info.globalcode.sql.dk.configuration.ConfigurationProvider; |
22 import info.globalcode.sql.dk.configuration.ConfigurationProvider; |
23 import info.globalcode.sql.dk.configuration.DatabaseDefinition; |
23 import info.globalcode.sql.dk.configuration.DatabaseDefinition; |
24 import info.globalcode.sql.dk.configuration.FormatterDefinition; |
24 import info.globalcode.sql.dk.configuration.FormatterDefinition; |
|
25 import info.globalcode.sql.dk.configuration.Property; |
25 import info.globalcode.sql.dk.formatting.ColumnsHeader; |
26 import info.globalcode.sql.dk.formatting.ColumnsHeader; |
|
27 import info.globalcode.sql.dk.formatting.FakeSqlArray; |
26 import info.globalcode.sql.dk.formatting.Formatter; |
28 import info.globalcode.sql.dk.formatting.Formatter; |
27 import info.globalcode.sql.dk.formatting.FormatterContext; |
29 import info.globalcode.sql.dk.formatting.FormatterContext; |
28 import info.globalcode.sql.dk.formatting.FormatterException; |
30 import info.globalcode.sql.dk.formatting.FormatterException; |
29 import java.io.BufferedReader; |
31 import java.io.BufferedReader; |
30 import java.io.InputStreamReader; |
32 import java.io.InputStreamReader; |
31 import java.io.PrintStream; |
33 import java.io.PrintStream; |
|
34 import java.sql.Array; |
32 import java.sql.Driver; |
35 import java.sql.Driver; |
|
36 import java.sql.DriverPropertyInfo; |
33 import java.sql.SQLException; |
37 import java.sql.SQLException; |
34 import java.util.ArrayList; |
38 import java.util.ArrayList; |
35 import java.util.EnumSet; |
39 import java.util.EnumSet; |
|
40 import java.util.HashSet; |
36 import java.util.List; |
41 import java.util.List; |
37 import java.util.ServiceLoader; |
42 import java.util.ServiceLoader; |
|
43 import java.util.Set; |
38 import java.util.logging.Level; |
44 import java.util.logging.Level; |
39 import java.util.logging.Logger; |
45 import java.util.logging.Logger; |
40 import javax.sql.rowset.RowSetMetaDataImpl; |
46 import javax.sql.rowset.RowSetMetaDataImpl; |
41 |
47 |
42 /** |
48 /** |
45 * @author Ing. František Kučera (frantovo.cz) |
51 * @author Ing. František Kučera (frantovo.cz) |
46 */ |
52 */ |
47 public class InfoLister { |
53 public class InfoLister { |
48 |
54 |
49 private static final Logger log = Logger.getLogger(InfoLister.class.getName()); |
55 private static final Logger log = Logger.getLogger(InfoLister.class.getName()); |
|
56 /** |
|
57 * Fake database name for output formatting |
|
58 */ |
|
59 public static final String CONFIG_DB_NAME = "sqldk_configuration"; |
50 private PrintStream out; |
60 private PrintStream out; |
51 private ConfigurationProvider configurationProvider; |
61 private ConfigurationProvider configurationProvider; |
52 private CLIOptions options; |
62 private CLIOptions options; |
53 private Formatter formatter; |
63 private Formatter formatter; |
54 |
64 |
115 |
126 |
116 for (FormatterDefinition fd : configurationProvider.getConfiguration().getFormatters()) { |
127 for (FormatterDefinition fd : configurationProvider.getConfiguration().getFormatters()) { |
117 data.add(new Object[]{fd.getName(), false, defaultFormatter.equals(fd.getName()), fd.getClassName()}); |
128 data.add(new Object[]{fd.getName(), false, defaultFormatter.equals(fd.getName()), fd.getClassName()}); |
118 } |
129 } |
119 |
130 |
120 printTable(formatter, header, data); |
131 printTable(formatter, header, data, "-- configured and built-in output formatters", null); |
121 |
132 |
122 |
133 |
123 } |
134 } |
124 |
135 |
125 public void listTypes() throws FormatterException, ConfigurationException { |
136 public void listTypes() throws FormatterException, ConfigurationException { |
126 ColumnsHeader header = constructHeader(new HeaderField("name", SQLType.VARCHAR), new HeaderField("code", SQLType.INTEGER)); |
137 ColumnsHeader header = constructHeader(new HeaderField("name", SQLType.VARCHAR), new HeaderField("code", SQLType.INTEGER)); |
127 List<Object[]> data = new ArrayList<>(); |
138 List<Object[]> data = new ArrayList<>(); |
128 for (SQLType sqlType : SQLType.values()) { |
139 for (SQLType sqlType : SQLType.values()) { |
129 data.add(new Object[]{sqlType.name(), sqlType.getCode()}); |
140 data.add(new Object[]{sqlType.name(), sqlType.getCode()}); |
130 } |
141 } |
131 printTable(formatter, header, data); |
142 printTable(formatter, header, data, "-- data types", null); |
132 log.log(Level.INFO, "Type names in --types option are case insensitive"); |
143 log.log(Level.INFO, "Type names in --types option are case insensitive"); |
133 } |
144 } |
134 |
145 |
135 public void listDatabases() throws ConfigurationException, FormatterException { |
146 public void listDatabases() throws ConfigurationException, FormatterException { |
136 ColumnsHeader header = constructHeader( |
147 ColumnsHeader header = constructHeader( |
146 for (DatabaseDefinition dd : configuredDatabases) { |
157 for (DatabaseDefinition dd : configuredDatabases) { |
147 data.add(new Object[]{dd.getName(), dd.getUserName(), dd.getUrl()}); |
158 data.add(new Object[]{dd.getName(), dd.getUserName(), dd.getUrl()}); |
148 } |
159 } |
149 } |
160 } |
150 |
161 |
151 printTable(formatter, header, data); |
162 printTable(formatter, header, data, "-- configured databases", null); |
152 } |
163 } |
153 |
164 |
154 public void listJdbcDrivers() throws FormatterException, ConfigurationException { |
165 public void listJdbcDrivers() throws FormatterException, ConfigurationException { |
155 ColumnsHeader header = constructHeader( |
166 ColumnsHeader header = constructHeader( |
156 new HeaderField("class", SQLType.VARCHAR), |
167 new HeaderField("class", SQLType.VARCHAR), |
165 data.add(new Object[]{ |
176 data.add(new Object[]{ |
166 d.getClass().getName(), |
177 d.getClass().getName(), |
167 d.getMajorVersion() + "." + d.getMinorVersion(), |
178 d.getMajorVersion() + "." + d.getMinorVersion(), |
168 d.getMajorVersion(), |
179 d.getMajorVersion(), |
169 d.getMinorVersion(), |
180 d.getMinorVersion(), |
170 d.jdbcCompliant()}); |
181 d.jdbcCompliant() |
171 } |
182 }); |
172 |
183 } |
173 printTable(formatter, header, data); |
184 |
174 |
185 printTable(formatter, header, data, "-- discovered JDBC drivers (available on the CLASSPATH)", null); |
|
186 } |
|
187 |
|
188 public void listJdbcProperties() throws FormatterException, ConfigurationException { |
|
189 for (String dbName : options.getDatabaseNamesToListProperties()) { |
|
190 ColumnsHeader header = constructHeader( |
|
191 new HeaderField("property_name", SQLType.VARCHAR), |
|
192 new HeaderField("required", SQLType.BOOLEAN), |
|
193 new HeaderField("choices", SQLType.ARRAY), |
|
194 new HeaderField("configured_value", SQLType.VARCHAR), |
|
195 new HeaderField("description", SQLType.VARCHAR)); |
|
196 List<Object[]> data = new ArrayList<>(); |
|
197 |
|
198 DatabaseDefinition dd = configurationProvider.getConfiguration().getDatabase(dbName); |
|
199 |
|
200 Driver driver = findDriver(dd); |
|
201 |
|
202 if (driver == null) { |
|
203 log.log(Level.WARNING, "No JDBC driver was found for DB: {0} with URL: {1}", new Object[]{dd.getName(), dd.getUrl()}); |
|
204 } else { |
|
205 log.log(Level.INFO, "For DB: {0} was found JDBC driver: {1}", new Object[]{dd.getName(), driver.getClass().getName()}); |
|
206 |
|
207 try { |
|
208 DriverPropertyInfo[] propertyInfos = driver.getPropertyInfo(dd.getUrl(), dd.getProperties().getJavaProperties()); |
|
209 |
|
210 Set<String> standardProperties = new HashSet<>(); |
|
211 |
|
212 for (DriverPropertyInfo pi : propertyInfos) { |
|
213 Array choices = new FakeSqlArray(pi.choices, SQLType.VARCHAR); |
|
214 data.add(new Object[]{ |
|
215 pi.name, |
|
216 pi.required, |
|
217 choices.getArray() == null ? "" : choices, |
|
218 pi.value == null ? "" : pi.value, |
|
219 pi.description |
|
220 }); |
|
221 standardProperties.add(pi.name); |
|
222 } |
|
223 |
|
224 for (Property p : dd.getProperties()) { |
|
225 if (!standardProperties.contains(p.getName())) { |
|
226 data.add(new Object[]{ |
|
227 p.getName(), |
|
228 "", |
|
229 "", |
|
230 p.getValue(), |
|
231 "" |
|
232 }); |
|
233 log.log(Level.WARNING, "Your configuration contains property „{0}“ not declared by the JDBC driver.", p.getName()); |
|
234 } |
|
235 } |
|
236 |
|
237 } catch (SQLException e) { |
|
238 log.log(Level.WARNING, "Error during getting property infos.", e); |
|
239 } |
|
240 |
|
241 List<Parameter> parameters = new ArrayList<>(); |
|
242 parameters.add(new NamedParameter("databgase", dbName, SQLType.VARCHAR)); |
|
243 parameters.add(new NamedParameter("driver_class", driver.getClass().getName(), SQLType.VARCHAR)); |
|
244 parameters.add(new NamedParameter("driver_major_version", driver.getMajorVersion(), SQLType.INTEGER)); |
|
245 parameters.add(new NamedParameter("driver_minor_version", driver.getMinorVersion(), SQLType.INTEGER)); |
|
246 |
|
247 printTable(formatter, header, data, "-- configured and configurable JDBC driver properties", parameters); |
|
248 } |
|
249 } |
|
250 |
|
251 } |
|
252 |
|
253 private Driver findDriver(DatabaseDefinition dd) { |
|
254 final ServiceLoader<Driver> drivers = ServiceLoader.load(Driver.class); |
|
255 for (Driver d : drivers) { |
|
256 try { |
|
257 if (d.acceptsURL(dd.getUrl())) { |
|
258 return d; |
|
259 } |
|
260 } catch (SQLException e) { |
|
261 log.log(Level.WARNING, "Error during finding JDBC driver for: " + dd.getName(), e); |
|
262 } |
|
263 } |
|
264 return null; |
175 } |
265 } |
176 |
266 |
177 public void testConnection() throws FormatterException, ConfigurationException { |
267 public void testConnection() throws FormatterException, ConfigurationException { |
178 ColumnsHeader header = constructHeader( |
268 ColumnsHeader header = constructHeader( |
179 new HeaderField("database_name", SQLType.VARCHAR), |
269 new HeaderField("database_name", SQLType.VARCHAR), |
226 |
316 |
227 private void println(String line) { |
317 private void println(String line) { |
228 out.println(line); |
318 out.println(line); |
229 } |
319 } |
230 |
320 |
231 private void printTable(Formatter formatter, ColumnsHeader header, List<Object[]> data) throws ConfigurationException, FormatterException { |
321 private void printTable(Formatter formatter, ColumnsHeader header, List<Object[]> data, String sql, List<Parameter> parameters) throws ConfigurationException, FormatterException { |
|
322 formatter.writeStartStatement(); |
|
323 |
|
324 if (sql != null) { |
|
325 formatter.writeQuery(sql); |
|
326 if (parameters != null) { |
|
327 formatter.writeParameters(parameters); |
|
328 } |
|
329 } |
|
330 |
232 formatter.writeStartResultSet(header); |
331 formatter.writeStartResultSet(header); |
233 |
332 |
234 for (Object[] row : data) { |
333 for (Object[] row : data) { |
235 formatter.writeStartRow(); |
334 formatter.writeStartRow(); |
236 for (Object cell : row) { |
335 for (Object cell : row) { |