1 24 25 package org.continuent.sequoia.controller.backend; 26 27 import java.sql.Connection ; 28 import java.sql.DatabaseMetaData ; 29 import java.sql.ResultSet ; 30 import java.sql.SQLException ; 31 32 import org.continuent.sequoia.common.i18n.Translate; 33 import org.continuent.sequoia.common.log.Trace; 34 import org.continuent.sequoia.controller.sql.schema.DatabaseColumn; 35 import org.continuent.sequoia.controller.sql.schema.DatabaseProcedure; 36 import org.continuent.sequoia.controller.sql.schema.DatabaseProcedureParameter; 37 import org.continuent.sequoia.controller.sql.schema.DatabaseSchema; 38 import org.continuent.sequoia.controller.sql.schema.DatabaseTable; 39 import org.continuent.sequoia.controller.sql.schema.DynamicDatabaseSchema; 40 41 51 public class DatabaseSQLMetaData 52 { 53 private Trace logger; 54 private Connection connection; 55 private DynamicDatabaseSchema dynamicDatabaseSchema; 56 private String schemaPattern; 57 58 66 public DatabaseSQLMetaData(Trace logger, Connection connection, 67 DynamicDatabaseSchema dynamicDatabaseSchema) 68 { 69 super(); 70 this.logger = logger; 71 this.connection = connection; 72 this.dynamicDatabaseSchema = dynamicDatabaseSchema; 73 this.schemaPattern = dynamicDatabaseSchema.getSchemaName(); 74 } 75 76 84 public final DatabaseSchema createDatabaseSchema(String vdbName) 85 throws SQLException 86 { 87 ResultSet rs = null; 88 89 boolean connectionWasAutocommit = connection.getAutoCommit(); 90 91 if (connectionWasAutocommit) 92 connection.setAutoCommit(false); 94 DatabaseMetaData metaData = connection.getMetaData(); 95 if (metaData == null) 96 { 97 logger.warn(Translate.get("backend.meta.received.null")); 98 return null; 99 } 100 101 if (logger.isDebugEnabled()) 102 logger.debug("Fetching schema" 103 + (dynamicDatabaseSchema.useStoredProcedures() 104 ? "" 105 : " with stored procedure information ") 106 + (dynamicDatabaseSchema.gatherSystemTables() ? "" : " not") 107 + " including system tables."); 108 109 DatabaseSchema databaseSchema = new DatabaseSchema(vdbName); 110 111 String [] types; 113 if (dynamicDatabaseSchema.gatherSystemTables()) 114 { 115 schemaPattern = null; 116 if (dynamicDatabaseSchema.useViews()) 117 types = new String []{"TABLE", "VIEW", "SYSTEM TABLE", "SYSTEM VIEW", "SEQUENCE"}; 118 else 119 types = new String []{"TABLE", "SYSTEM TABLE", "SEQUENCE"}; 120 } 121 else 122 { 123 if (dynamicDatabaseSchema.useViews()) 124 types = new String []{"TABLE", "VIEW", "SEQUENCE"}; 125 else 126 types = new String []{"TABLE", "SEQUENCE"}; 127 } 128 129 try 136 { 137 rs = metaData.getTables(null, schemaPattern, "%", types); 138 } 139 catch (Exception e) 140 { 141 logger.error(Translate.get("backend.meta.view.not.supported"), e); 143 if (dynamicDatabaseSchema.gatherSystemTables()) 144 types = new String []{"TABLE", "SYSTEM TABLE"}; 145 else 146 types = new String []{"TABLE"}; 147 rs = metaData.getTables(null, schemaPattern, "%", types); 148 } 149 150 if (rs == null) 151 { 152 logger.warn(Translate.get("backend.meta.received.null")); 153 if (connectionWasAutocommit) 154 connection.commit(); 155 return null; 156 } 157 158 String tableName; 159 String schemaName; 160 DatabaseTable table = null; 161 while (rs.next()) 162 { 163 schemaName = rs.getString(2); 165 tableName = rs.getString(3); 166 String type = rs.getString(4); 167 if (logger.isDebugEnabled()) 168 logger.debug(Translate.get("backend.meta.found.table", schemaName + "." 169 + tableName)); 170 171 table = new DatabaseTable(tableName); 173 table.setSchema(schemaName); 174 if (!type.equals("VIEW")) 175 { 176 getExportedKeys(metaData, table); 177 getImportedKeys(metaData, table); 178 } 179 databaseSchema.addTable(table); 180 181 if (dynamicDatabaseSchema.useColumns()) 183 { 184 getColumns(metaData, table); 185 186 if (!type.equals("VIEW")) 189 { 190 getPrimaryKeys(metaData, table); 191 } 192 } 193 } 194 195 if (dynamicDatabaseSchema.useStoredProcedures()) 197 getProcedures(metaData, databaseSchema); 198 199 try 200 { 201 rs.close(); 202 } 203 catch (Exception ignore) 204 { 205 } 206 207 if (connectionWasAutocommit) 208 { 209 try 210 { 211 connection.commit(); 212 } 213 catch (Exception ignore) 214 { 215 } 217 218 try 219 { 220 connection.setAutoCommit(true); 222 } 223 catch (SQLException e1) 224 { 225 } 227 } 228 229 return databaseSchema; 230 } 231 232 236 private void getProcedures(DatabaseMetaData metaData, DatabaseSchema schema) 237 { 238 if (logger.isDebugEnabled()) 239 logger.debug(Translate.get("backend.meta.get.procedures")); 240 241 ResultSet rs = null; 242 ResultSet rs2 = null; 243 try 244 { 245 rs = metaData.getProcedures(null, schemaPattern, "%"); 247 248 if (rs == null) 249 { 250 logger.warn(Translate.get("backend.meta.get.procedures.failed", 251 metaData.getConnection().getCatalog())); 252 return; 253 } 254 255 while (rs.next()) 256 { 257 DatabaseProcedure procedure = new DatabaseProcedure(rs.getString(3), rs 262 .getString(7), rs.getShort(8)); 263 264 if (!dynamicDatabaseSchema.useStoredProcedures()) 266 { 267 if (logger.isDebugEnabled() 268 && schema.getProcedure(procedure.getName()) != null) 269 { 270 logger.debug(Translate 271 .get("backend.meta.procedure.already.in.schema", procedure 272 .getName())); 273 } 274 continue; 275 } 276 277 rs2 = metaData 279 .getProcedureColumns(null, null, procedure.getName(), "%"); 280 if (rs2 == null) 281 logger.warn(Translate.get("backend.meta.get.procedure.params.failed", 282 procedure.getName())); 283 else 284 { 285 while (rs2.next()) 286 { 287 DatabaseProcedureParameter param = new DatabaseProcedureParameter( 299 rs2.getString(4), rs2.getInt(5), rs2.getInt(6), rs2 300 .getString(7), rs2.getFloat(8), rs2.getInt(9), rs2 301 .getInt(10), rs2.getInt(11), rs2.getInt(12), rs2 302 .getString(13)); 303 procedure.addParameter(param); 304 if (logger.isDebugEnabled()) 305 logger.debug(procedure.getName() + ": adding parameter " 306 + param.getName()); 307 } 308 rs2.close(); 309 } 310 311 if (!schema.getProcedures().containsValue(procedure)) 313 { 314 schema.addProcedure(procedure); 315 if (logger.isDebugEnabled()) 316 logger.debug(Translate.get("backend.meta.procedure.added", 317 procedure.getKey())); 318 } 319 else if (logger.isDebugEnabled()) 320 { 321 logger.debug(Translate.get( 322 "backend.meta.procedure.already.in.schema", procedure.getName())); 323 } 324 } 325 } 326 catch (Exception e) 327 { 328 logger.error(Translate.get("backend.meta.get.procedures.failed", e 329 .getMessage()), e); 330 } 331 finally 332 { 333 try 334 { 335 rs.close(); 336 } 337 catch (Exception ignore) 338 { 339 } 340 try 341 { 342 rs2.close(); 343 } 344 catch (Exception ignoreAsWell) 345 { 346 } 347 } 348 } 349 350 358 private void getColumns(DatabaseMetaData metaData, DatabaseTable table) 359 throws SQLException 360 { 361 ResultSet rs = null; 362 try 363 { 364 rs = metaData.getColumns(null, table.getSchema(), table.getName(), "%"); 370 371 if (rs == null) 372 { 373 logger.warn(Translate.get("backend.meta.get.columns.failed", table 374 .getSchema() 375 + "." + table.getName())); 376 return; 377 } 378 379 DatabaseColumn column = null; 380 int type; 381 while (rs.next()) 382 { 383 type = rs.getShort(5); 386 column = new DatabaseColumn(rs.getString(4), false, type); 387 table.addColumn(column); 388 389 if (logger.isDebugEnabled()) 390 logger.debug(Translate.get("backend.meta.found.column", rs 391 .getString(4))); 392 } 393 } 394 catch (SQLException e) 395 { 396 throw new SQLException (Translate.get("backend.meta.get.columns.failed", 397 table.getSchema() + "." + table.getName())); 398 } 399 finally 400 { 401 try 402 { 403 rs.close(); 404 } 405 catch (Exception ignore) 406 { 407 } 408 } 409 } 410 411 419 private void getExportedKeys(DatabaseMetaData metaData, DatabaseTable table) 420 { 421 ResultSet rs = null; 422 try 423 { 424 429 rs = metaData.getExportedKeys(null, table.getSchema(), table.getName()); 430 431 if (rs == null) 432 { 433 logger.warn(Translate.get("backend.meta.get.exported.keys.failed", 434 table.getSchema() + "." + table.getName())); 435 return; 436 } 437 438 String referencingTableName = null; 439 while (rs.next()) 440 { 441 referencingTableName = rs.getString(7); 443 if (referencingTableName == null) 444 continue; 445 if (logger.isDebugEnabled()) 446 logger.debug(Translate.get("backend.meta.found.exported.key", 447 referencingTableName)); 448 449 table.addDependingTable(referencingTableName); 451 } 452 } 453 catch (SQLException e) 454 { 455 logger.warn(Translate.get("backend.meta.get.exported.keys.failed", table 456 .getSchema() 457 + "." + table.getName()), e); 458 } 459 finally 460 { 461 try 462 { 463 rs.close(); 464 } 465 catch (Exception ignore) 466 { 467 } 468 } 469 } 470 471 479 private void getImportedKeys(DatabaseMetaData metaData, DatabaseTable table) 480 { 481 ResultSet rs = null; 482 try 483 { 484 489 rs = metaData.getImportedKeys(null, table.getSchema(), table.getName()); 490 491 if (rs == null) 492 { 493 logger.warn(Translate.get("backend.meta.get.imported.keys.failed", 494 table.getSchema() + "." + table.getName())); 495 return; 496 } 497 498 String referencedTableName = null; 499 while (rs.next()) 500 { 501 referencedTableName = rs.getString(3); 503 if (referencedTableName == null) 504 continue; 505 if (logger.isDebugEnabled()) 506 logger.debug(Translate.get("backend.meta.found.imported.key", 507 referencedTableName)); 508 509 table.addDependingTable(referencedTableName); 511 } 512 } 513 catch (SQLException e) 514 { 515 logger.warn(Translate.get("backend.meta.get.imported.keys.failed", table 516 .getSchema() 517 + "." + table.getName()), e); 518 } 519 finally 520 { 521 try 522 { 523 rs.close(); 524 } 525 catch (Exception ignore) 526 { 527 } 528 } 529 } 530 531 539 private void getPrimaryKeys(DatabaseMetaData metaData, DatabaseTable table) 540 throws SQLException 541 { 542 ResultSet rs = null; 543 try 544 { 545 550 rs = metaData.getPrimaryKeys(null, table.getSchema(), table.getName()); 551 552 if (rs == null) 553 { 554 logger.warn(Translate.get("backend.meta.get.primary.keys.failed", table 555 .getSchema() 556 + "." + table.getName())); 557 return; 558 } 559 560 String columnName = null; 561 while (rs.next()) 562 { 563 564 columnName = rs.getString(4); 567 if (columnName == null) 568 continue; 569 if (logger.isDebugEnabled()) 570 logger.debug(Translate.get("backend.meta.found.primary.key", 571 columnName)); 572 573 table.getColumn(columnName).setIsUnique(true); 575 } 576 } 577 catch (SQLException e) 578 { 579 throw new SQLException (Translate.get( 580 "backend.meta.get.primary.keys.failed", table.getSchema() + "." 581 + table.getName())); 582 } 583 finally 584 { 585 try 586 { 587 rs.close(); 588 } 589 catch (Exception ignore) 590 { 591 } 592 } 593 } 594 595 } 596 | Popular Tags |