1 19 20 package org.netbeans.modules.dbschema.jdbcimpl; 21 22 import java.beans.PropertyChangeListener ; 23 import java.beans.PropertyChangeSupport ; 24 import java.sql.*; 25 import java.util.*; 26 27 import org.netbeans.modules.dbschema.*; 28 import org.netbeans.modules.dbschema.util.*; 29 30 public class SchemaElementImpl extends DBElementImpl implements SchemaElement.Impl { 31 32 private DBElementsCollection tables; 33 34 private DBIdentifier _schema; 35 private DBIdentifier _catalog; 36 private String _url; 37 private String _username; 38 private String _driver; 39 private String _databaseProductName; 40 private String _databaseProductVersion; 41 private String _driverName; 42 private String _driverVersion; 43 44 private transient DatabaseMetaData dmd; 45 private transient String catalog; 46 47 private transient volatile boolean stop; 48 49 public transient PropertyChangeSupport propertySupport = new PropertyChangeSupport (this); 50 51 private transient int progress; 52 53 54 public SchemaElementImpl() { 55 this(null); 56 } 57 58 public SchemaElementImpl(ConnectionProvider cp) { 59 tables = new DBElementsCollection(this, new TableElement[0]); 60 61 Object hc = String.valueOf(tables.hashCode()); 64 while (DBElementsCollection.instances.contains(hc)) { 65 tables = new DBElementsCollection(this, new TableElement[0]); 66 hc = String.valueOf(tables.hashCode()); 67 } 68 DBElementsCollection.instances.add(hc); 69 70 if (cp != null) { 71 try { 72 String schema; 73 74 dmd = cp.getDatabaseMetaData(); 75 76 _url = dmd.getURL(); 77 _username = dmd.getUserName(); 78 schema = cp.getSchema(); 80 _schema = schema == null ? DBIdentifier.create("") : DBIdentifier.create(schema); catalog = cp.getConnection().getCatalog(); 82 _catalog = catalog == null ? DBIdentifier.create("") : DBIdentifier.create(catalog); _driver = cp.getDriver(); 84 _databaseProductName = dmd.getDatabaseProductName().trim(); 85 _databaseProductVersion = dmd.getDatabaseProductVersion(); 86 _driverName = dmd.getDriverName(); 87 _driverVersion = dmd.getDriverVersion(); 88 } catch (Exception exc) { 89 exc.printStackTrace(); 90 } 91 } 92 93 stop = false; 94 } 95 96 public void setName(DBIdentifier name) throws DBException { 97 int pos; 98 String fullName = name.getFullName(); 99 100 if (fullName == null) { 101 fullName = name.getName(); 102 name.setFullName(fullName); 103 } 104 105 pos = fullName.lastIndexOf("/"); 106 if (pos != -1) 107 name.setName(fullName.substring(pos + 1)); 108 else if (fullName.indexOf(".") != -1) 109 name.setName(fullName); 110 111 _name = name; 112 } 113 114 public DBIdentifier getName() { 115 return _name; 116 } 117 118 123 public int getStatus() { 124 return SchemaElement.STATUS_OK; 126 } 127 128 132 public void setSchema(DBIdentifier schema) throws DBException { 133 _schema = schema; 134 } 135 136 140 public DBIdentifier getSchema() { 141 return _schema; 142 } 143 144 148 public void setCatalog(DBIdentifier catalog) throws DBException { 149 _catalog = catalog; 150 } 151 152 156 public DBIdentifier getCatalog() { 157 return _catalog; 158 } 159 160 165 public void changeTables(TableElement[] elems,int action) throws DBException { 166 tables.changeElements(elems, action); 167 } 168 169 172 public TableElement[] getTables() { 173 DBElement[] dbe = tables.getElements(); 174 return (TableElement[]) Arrays.asList(dbe).toArray(new TableElement[dbe.length]); 175 } 176 177 181 public TableElement getTable(DBIdentifier name) { 182 return (TableElement) tables.find(name); 183 } 184 185 public void initTables(ConnectionProvider cp) { 186 initTables(cp, null, null, false); } 188 189 public void initTables(ConnectionProvider cp, LinkedList t, LinkedList v) { 190 initTables(cp, t, v, false); } 192 193 public void initTables(ConnectionProvider cp, LinkedList t, LinkedList v, boolean allTables) { 194 if (cp !=null) 195 try { 196 progress = 0; 197 LinkedList tables = new LinkedList(); 198 LinkedList views = new LinkedList(); 199 LinkedList tablesTmp = new LinkedList(); 200 LinkedList viewsTmp = new LinkedList(); 201 String user = cp.getSchema(); 203 List recycleBinTables; 204 ResultSet rs; 205 206 DDLBridge bridge = null; 207 if (IDEUtil.isIDERunning()) 208 bridge = new DDLBridge(cp.getConnection(), cp.getSchema(), dmd); 209 210 if ("Oracle".equals(dmd.getDatabaseProductName()) && dmd.getDatabaseMajorVersion() >= 10) { recycleBinTables = getOracleRecycleBinTables(); 213 } else { 214 recycleBinTables = Collections.EMPTY_LIST; 215 } 216 217 if (bridge != null) { 219 bridge.getDriverSpecification().getTables("%", new String [] {"TABLE"}); rs = bridge.getDriverSpecification().getResultSet(); 221 } else 222 rs = dmd.getTables(catalog, user, "%", new String [] {"TABLE"}); 224 if (rs != null) { 225 while (rs.next()) { 226 if (isStop()) { 227 rs.close(); 228 return; 229 } 230 231 String tableTmp; 232 if (bridge != null) 233 tableTmp = (String ) bridge.getDriverSpecification().getRow().get(new Integer (3)); 234 else 235 tableTmp = rs.getString("TABLE_NAME").trim(); 237 if (!recycleBinTables.contains(tableTmp)) { 238 tablesTmp.add(tableTmp); 239 } 240 } 241 rs.close(); 242 } 243 244 rs = null; 245 if (bridge != null) 246 if (bridge.getDriverSpecification().areViewsSupported()) { 247 bridge.getDriverSpecification().getTables("%", new String [] {"VIEW"}); rs = bridge.getDriverSpecification().getResultSet(); 249 } 250 else 251 if (MetaDataUtil.areViewsSupported(dmd.getDatabaseProductName())) 252 rs = dmd.getTables(catalog, user, "%", new String [] {"VIEW"}); 254 if (rs != null) { 255 while (rs.next()) { 256 if (isStop()) { 257 rs.close(); 258 return; 259 } 260 261 if (bridge != null) 262 viewsTmp.add((String ) bridge.getDriverSpecification().getRow().get(new Integer (3))); 263 else 264 viewsTmp.add(rs.getString("TABLE_NAME").trim()); } 266 rs.close(); 267 } 268 270 if (t == null && v == null) { 271 tables = tablesTmp; 272 views = viewsTmp; 273 } else { 274 t = checkNames(t, tablesTmp); 275 v = checkNames(v, viewsTmp); 276 277 if (allTables) 278 tables = t; 279 else 280 tables = checkReferences(t, bridge, user); 281 282 views = v; 283 } 284 285 propertySupport.firePropertyChange("totalCount", null, new Integer (2 * tables.size() + views.size())); 289 initTables(cp, tables); 290 initViews(cp, views, bridge); 291 } catch (Exception exc) { 292 if (Boolean.getBoolean("netbeans.debug.exceptions")) exc.printStackTrace(); 294 } 295 } 296 297 private LinkedList checkNames(LinkedList toCheck, LinkedList names) { 298 LinkedList result = new LinkedList(); 299 300 for (int i = 0; i < toCheck.size(); i++) { 301 Object table = toCheck.get(i); 302 303 if (names.contains(table)) 304 result.add(table); 305 else 306 if (Boolean.getBoolean("netbeans.debug.exceptions")) System.out.println("Cannot find " + table + " table in the database."); } 309 310 return result; 311 } 312 313 private LinkedList checkReferences(LinkedList tables, DDLBridge bridge, String schema) throws SQLException { 314 ResultSet rs; 315 String pkSchema; 316 String fkSchema; 317 String refTable; 318 319 for (int i = 0; i < tables.size(); i++) { if (bridge != null) { 321 bridge.getDriverSpecification().getImportedKeys(tables.get(i).toString()); 322 rs = bridge.getDriverSpecification().getResultSet(); 323 } else 324 rs = dmd.getImportedKeys(catalog, schema, tables.get(i).toString()); 325 326 if (rs != null) { 327 HashMap rset = new HashMap(); 328 String c1, c2, s1, s2; 329 while (rs.next()) { 330 if (bridge != null) { 331 rset = bridge.getDriverSpecification().getRow(); 332 333 c1 = (String ) rset.get(new Integer (1)); 335 s1 = (String ) rset.get(new Integer (2)); 336 c2 = (String ) rset.get(new Integer (5)); 337 s2 = (String ) rset.get(new Integer (6)); 338 339 if (comp(c1, c2)) { 340 if (! comp(s1, s2)) 341 continue; 342 } else 343 continue; 344 345 pkSchema = (String ) rset.get(new Integer (2)); 346 fkSchema = (String ) rset.get(new Integer (6)); 347 if ((pkSchema == fkSchema) || (pkSchema.equals(fkSchema))) { 348 refTable = (String ) rset.get(new Integer (3)); 349 if (! tables.contains(refTable)) 350 tables.add(refTable); 351 } 352 rset.clear(); 353 } else { 354 c1 = rs.getString("PKTABLE_CAT"); s1 = rs.getString("PKTABLE_SCHEM"); c2 = rs.getString("FKTABLE_CAT"); s2 = rs.getString("FKTABLE_SCHEM"); 360 if (comp(c1, c2)) { 361 if (! comp(s1, s2)) 362 continue; 363 } else 364 continue; 365 366 pkSchema = rs.getString("PKTABLE_SCHEM"); if (pkSchema != null) { 368 pkSchema = pkSchema.trim(); 369 } 370 fkSchema = rs.getString("FKTABLE_SCHEM"); if (fkSchema != null) { 372 fkSchema = fkSchema.trim(); 373 } 374 if ((pkSchema == fkSchema) || (pkSchema.equals(fkSchema))) { 375 refTable = rs.getString("PKTABLE_NAME").trim(); if (! tables.contains(refTable)) 377 tables.add(refTable); 378 } 379 } 380 } 381 rs.close(); 382 } 383 } 384 385 return tables; 386 } 387 388 private void initTables(ConnectionProvider cp, LinkedList tables) throws DBException { 389 String name; 390 391 for (int i = 0; i < tables.size(); i++) { 392 if (isStop()) 393 return; 394 395 name = tables.get(i).toString(); 396 propertySupport.firePropertyChange("tableName", null, name); TableElementImpl tei = new TableElementImpl(name); 398 tei.setTableOrView(true); 399 TableElement[] te = {new TableElement(tei, (SchemaElement) element)}; 400 401 tei.initColumns(cp); 402 tei.initIndexes(cp); 403 changeTables(te, DBElement.Impl.ADD); 404 405 progress++; 406 propertySupport.firePropertyChange("progress", null, new Integer (progress)); } 408 409 TableElement te; 410 String tableName; 411 for (int i = 0; i < tables.size(); i++) { 412 if (isStop()) 413 return; 414 415 tableName = tables.get(i).toString(); 416 te = getTable(DBIdentifier.create(tableName)); 417 if (te != null) { 418 propertySupport.firePropertyChange("FKt", null, tableName); ((TableElementImpl) te.getElementImpl()).initKeys(cp, 0, tableName); 420 } 421 422 progress++; 423 propertySupport.firePropertyChange("progress", null, new Integer (progress)); } 425 } 426 427 private void initViews(ConnectionProvider cp, LinkedList views, DDLBridge bridge) throws DBException, SQLException { 428 String name; 429 ResultSet rs; 430 431 for (int i = 0; i < views.size(); i++) { 432 if (isStop()) 433 return; 434 435 name = views.get(i).toString(); 436 propertySupport.firePropertyChange("viewName", null, name); TableElementImpl tei = new TableElementImpl(name); 438 tei.setTableOrView(false); 439 TableElement te = new TableElement(tei, (SchemaElement) element); 440 tei.initColumns(cp); 441 442 String database = dmd.getDatabaseProductName(); 443 if (database!=null){ database = database.trim(); 445 } 446 else{ 447 database=""; } 449 if (database.equalsIgnoreCase("Oracle") || database.equalsIgnoreCase("Microsoft SQL Server")) { propertySupport.firePropertyChange("FKv", null, name); 452 ViewDependency vd = new ViewDependency(cp, cp.getSchema(), name); 453 LinkedList tables = new LinkedList(); 454 LinkedList columns = new LinkedList(); 455 456 tables.clear(); 457 columns.clear(); 458 vd.constructPK(); 459 tables = vd.getTables(); 460 columns = vd.getColumns(); 461 if (! columns.isEmpty()) { 462 boolean all = false; 463 for (int k = 0; k < columns.size(); k++) 464 if (((String ) columns.get(k)).trim().endsWith("*")) { 466 all = true; 467 break; 468 } 469 470 boolean capture = true; 471 LinkedList pkTables = new LinkedList(); 472 for (int j = 0; j < tables.size(); j++) { 473 if (isStop()) 474 return; 475 476 if (bridge != null) { 478 bridge.getDriverSpecification().getPrimaryKeys(tables.get(j).toString()); 479 rs = bridge.getDriverSpecification().getResultSet(); 480 } else 481 rs = cp.getDatabaseMetaData().getPrimaryKeys(cp.getConnection().getCatalog(), cp.getSchema(), tables.get(j).toString()); 482 483 if (rs != null) { 484 if (! all) { 485 String colName; 486 HashMap rset = new HashMap(); 487 while (rs.next()) { 488 if (bridge != null) { 489 rset = bridge.getDriverSpecification().getRow(); 490 colName = (String ) rset.get(new Integer (4)); 491 rset.clear(); 492 } else 493 colName = rs.getString("COLUMN_NAME").trim(); 495 if (columns.contains(colName.toLowerCase()) || columns.contains(tables.get(j).toString().toLowerCase() + "." + colName.toLowerCase())) 496 continue; 497 else { 498 capture = false; 499 break; 500 } 501 } 502 } 503 504 if (capture) 505 pkTables.add(tables.get(j).toString()); 506 507 rs.close(); 508 } 509 } 510 511 if (capture) 512 for (int j = 0; j < pkTables.size(); j++) { 513 tei.initIndexes(cp, pkTables.get(j).toString()); 515 tei.initKeys(cp, 1, pkTables.get(j).toString()); 516 517 LinkedList tempList = new LinkedList(); 518 UniqueKeyElement[] keys = te.getUniqueKeys(); 519 for (int k = 0; k < keys.length; k++) 520 if (keys[k].isPrimaryKey()) 521 tempList.add(keys[k]); 522 523 keys = new UniqueKeyElement[tempList.size()]; 524 for (int k = 0; k < tempList.size(); k++) 525 keys[k] = (UniqueKeyElement) tempList.get(k); 526 te.setKeys(keys); 527 528 IndexElement[] indexes = new IndexElement[keys.length]; 529 for (int k = 0; k < keys.length; k++) 530 indexes[k] = ((UniqueKeyElement) keys[k]).getAssociatedIndex(); 531 te.setIndexes(indexes); 532 } 533 534 if (te.getUniqueKeys().length > 1) { 536 IndexElementImpl iei = new IndexElementImpl(tei, "GENERATED_PK_" + tei.getName().getName(), true); 537 IndexElement[] ie = {new IndexElement(iei, te)}; 538 IndexElement[] ies = te.getIndexes(); 539 for (int j = 0; j < ies.length; j++) 540 iei.changeColumns(ies[j].getColumns(), DBElement.Impl.ADD); 541 te.setIndexes(ie); 542 543 IndexElement ii = te.getIndexes()[0]; 544 UniqueKeyElementImpl ukei = new UniqueKeyElementImpl(ii.getName().getName(), true); 545 UniqueKeyElement uke = new UniqueKeyElement(ukei, te, ii); 546 uke.setColumns(ii.getColumns()); 547 tei.changeKeys(new UniqueKeyElement[] {uke}, DBElement.Impl.SET); 548 } 549 550 LinkedList toCapture = new LinkedList(); 552 LinkedList validFKs = new LinkedList(); 553 LinkedList fkTables = new LinkedList(); 554 for (int j = 0; j < tables.size(); j++) { 555 if (isStop()) 556 return; 557 558 if (bridge != null) { 559 bridge.getDriverSpecification().getImportedKeys(tables.get(j).toString()); 560 rs = bridge.getDriverSpecification().getResultSet(); 561 } else 562 rs = cp.getDatabaseMetaData().getImportedKeys(cp.getConnection().getCatalog(), cp.getSchema(), tables.get(j).toString()); 563 564 if (rs != null) { 565 HashMap rset = new HashMap(); 566 LinkedList local = new LinkedList(); 567 LinkedList ref = new LinkedList(); 568 LinkedList fk = new LinkedList(); 569 String fkName, c1, c2, s1, s2; 570 while (rs.next()) { 571 if (bridge != null) { 572 rset = bridge.getDriverSpecification().getRow(); 573 574 c1 = (String ) rset.get(new Integer (1)); 576 s1 = (String ) rset.get(new Integer (2)); 577 c2 = (String ) rset.get(new Integer (5)); 578 s2 = (String ) rset.get(new Integer (6)); 579 580 if (comp(c1, c2)) { 581 if (! comp(s1, s2)) 582 continue; 583 } else 584 continue; 585 586 fkName = (String ) rset.get(new Integer (12)); 587 if (fkName == null) 588 continue; 589 else 590 fkName = fkName.trim(); 591 local.add(fkName + "." + ((String ) rset.get(new Integer (7))) + "." + ((String ) rset.get(new Integer (8)))); ref.add(fkName + "." + ((String ) rset.get(new Integer (3))) + "." + ((String ) rset.get(new Integer (4)))); if (! fk.contains(fkName)) 595 fk.add(fkName); 596 rset.clear(); 597 } else { 598 c1 = rs.getString("PKTABLE_CAT"); s1 = rs.getString("PKTABLE_SCHEM"); c2 = rs.getString("FKTABLE_CAT"); s2 = rs.getString("FKTABLE_SCHEM"); 604 if (comp(c1, c2)) { 605 if (! comp(s1, s2)) 606 continue; 607 } else 608 continue; 609 610 fkName = rs.getString("FK_NAME"); if (fkName == null) 612 continue; 613 else 614 fkName = fkName.trim(); 615 local.add(fkName + "." + rs.getString("FKTABLE_NAME").trim() + "." + rs.getString("FKCOLUMN_NAME").trim()); ref.add(fkName + "." + rs.getString("PKTABLE_NAME").trim() + "." + rs.getString("PKCOLUMN_NAME").trim()); if (! fk.contains(fkName)) 619 fk.add(fkName); 620 } 621 } 622 rs.close(); 623 624 String colName; 625 for (int k = 0; k < fk.size(); k++) { 626 fkName = fk.get(k).toString(); 627 for (int l = 0; l < local.size(); l++) { 628 colName = local.get(l).toString(); 629 if (colName.startsWith(fkName)) 630 colName = colName.substring(colName.lastIndexOf(".") + 1).toLowerCase(); 631 else 632 continue; 633 634 if (all || columns.contains(colName) || columns.contains(tables.get(j).toString().toLowerCase() + "." + colName)) { 635 continue; 636 } else { 637 fk.set(k, null); 638 break; 639 } 640 } 641 642 if (fk.get(k) != null) 643 for (int l = 0; l < ref.size(); l++) { 644 colName = ref.get(l).toString(); 645 if (colName.startsWith(fkName)) { 646 colName = colName.substring(colName.indexOf(".") + 1, colName.lastIndexOf(".")); 647 if (getTable(DBIdentifier.create(colName)) == null) 648 toCapture.add(colName); 649 break; 650 } 651 } 652 } 653 654 String tblName = tables.get(j).toString(); 655 for (int k = 0; k < fk.size(); k++) { 656 Object o = fk.get(k); 657 if (o != null) { 658 validFKs.add(o); 659 if (! fkTables.contains(tblName)) 660 fkTables.add(tblName); 661 } 662 } 663 } 664 } 665 666 initTables(cp, checkReferences(toCapture, bridge, cp.getSchema())); 667 668 for (int j = 0; j < fkTables.size(); j++) 669 tei.initKeys(cp, 2, fkTables.get(j).toString()); 670 671 LinkedList tempList = new LinkedList(); 672 ForeignKeyElement[] fke = te.getForeignKeys(); 673 UniqueKeyElement[] uke = te.getUniqueKeys(); 674 for (int j = 0; j < fke.length; j++) 675 if (validFKs.contains(fke[j].getName().getName())) 676 tempList.add(fke[j]); 677 KeyElement[] ke = new KeyElement[uke.length + tempList.size()]; 678 for (int j = 0; j < uke.length; j++) 679 ke[j] = uke[j]; 680 int idx = uke.length; 681 for (int j = 0; j < tempList.size(); j++) 682 ke[j + idx] = (ForeignKeyElement) tempList.get(j); 683 684 te.setKeys(ke); 685 686 } 687 } 688 689 changeTables(new TableElement[] {te}, DBElement.Impl.ADD); 690 691 progress++; 692 propertySupport.firePropertyChange("progress", null, new Integer (progress)); } 694 } 695 696 private List getOracleRecycleBinTables() { 697 List result = new ArrayList(); 698 try { 699 Statement stmt = dmd.getConnection().createStatement(); 700 try { 701 ResultSet rs = stmt.executeQuery("SELECT OBJECT_NAME FROM RECYCLEBIN WHERE TYPE = 'TABLE'"); try { 703 while (rs.next()) { 704 result.add(rs.getString("OBJECT_NAME")); } 706 } finally { 707 rs.close(); 708 } 709 } finally { 710 stmt.close(); 711 } 712 } catch (SQLException exc) { 713 if (Boolean.getBoolean("netbeans.debug.exceptions")) { exc.printStackTrace(); 716 } 717 result = Collections.EMPTY_LIST; 718 } 719 return result; 720 } 721 722 725 public String getUrl() { 726 return _url; 727 } 728 729 732 public void setUrl(String url) throws DBException { 733 _url = url; 734 } 735 736 739 public String getUsername() { 740 return _username; 741 } 742 743 746 public void setUsername(String username) throws DBException { 747 _username = username; 748 } 749 750 753 public String getDriver() { 754 return _driver; 755 } 756 757 760 public void setDriver(String driver) { 761 _driver = driver; 762 } 763 764 767 public String getDatabaseProductName() { 768 return _databaseProductName; 769 } 770 771 774 public void setDatabaseProductName(String databaseProductName) throws DBException { 775 _databaseProductName = databaseProductName; 776 } 777 778 781 public String getDatabaseProductVersion() { 782 return _databaseProductVersion; 783 } 784 785 788 public void setDatabaseProductVersion(String databaseProductVersion) throws DBException { 789 _databaseProductVersion = databaseProductVersion; 790 } 791 792 795 public String getDriverName() { 796 return _driverName; 797 } 798 799 802 public void setDriverName(String driverName) throws DBException { 803 _driverName = driverName; 804 } 805 806 809 public String getDriverVersion() { 810 return _driverVersion; 811 } 812 813 816 public void setDriverVersion(String driverVersion) throws DBException { 817 _driverVersion = driverVersion; 818 } 819 820 public boolean isStop() { 821 return stop; 822 } 823 824 public void setStop(boolean stop) { 825 this.stop = stop; 826 } 827 828 public void addPropertyChangeListener(PropertyChangeListener l) { 830 propertySupport.addPropertyChangeListener (l); 831 } 832 833 public void removePropertyChangeListener(PropertyChangeListener l) { 834 propertySupport.removePropertyChangeListener (l); 835 } 836 837 839 843 public DBElementsCollection getTableCollection () 844 { 845 return tables; 846 } 847 848 853 public void setTableCollection (DBElementsCollection collection) 854 { 855 tables = collection; 856 } 857 } 858 | Popular Tags |