1 19 20 package org.netbeans.modules.dbschema.jdbcimpl; 21 22 import java.sql.*; 23 import java.util.*; 24 25 import org.netbeans.modules.dbschema.*; 26 import org.netbeans.modules.dbschema.util.*; 27 28 public class TableElementImpl extends DBElementImpl implements TableElement.Impl { 29 30 private DBElementsCollection columns; 31 private DBElementsCollection indexes; 32 private DBElementsCollection keys; 33 transient private DBElementsCollection columnPairs; 34 35 private String table; 36 37 private boolean isTable; 38 39 public TableElementImpl() { 40 this(null); 41 } 42 43 44 public TableElementImpl(String table) { 45 super(table); 46 columns = new DBElementsCollection(this, new ColumnElement[0]); 47 Object hc = String.valueOf(columns.hashCode()); 50 while (DBElementsCollection.instances.contains(hc)) { 51 columns = new DBElementsCollection(this, new ColumnElement[0]); 52 hc = String.valueOf(columns.hashCode()); 53 } 54 DBElementsCollection.instances.add(hc); 55 56 indexes = new DBElementsCollection(this, new IndexElement[0]); 57 hc = String.valueOf(indexes.hashCode()); 60 while (DBElementsCollection.instances.contains(hc)) { 61 indexes = new DBElementsCollection(this, new IndexElement[0]); 62 hc = String.valueOf(indexes.hashCode()); 63 } 64 DBElementsCollection.instances.add(hc); 65 66 keys = new DBElementsCollection(this, new KeyElement[0]); 67 hc = String.valueOf(keys.hashCode()); 70 while (DBElementsCollection.instances.contains(hc)) { 71 keys = new DBElementsCollection(this, new KeyElement[0]); 72 hc = String.valueOf(keys.hashCode()); 73 } 74 DBElementsCollection.instances.add(hc); 75 76 columnPairs = new DBElementsCollection(this, new ColumnPairElement[0]); 77 hc = String.valueOf(columnPairs.hashCode()); 80 while (DBElementsCollection.instances.contains(hc)) { 81 columnPairs = new DBElementsCollection(this, new ColumnPairElement[0]); 82 hc = String.valueOf(columnPairs.hashCode()); 83 } 84 DBElementsCollection.instances.add(hc); 85 86 this.table = table; 87 } 88 89 92 public DBIdentifier getName() { 93 if (_name.getFullName() == null) 94 _name.setFullName(((TableElement) element).getDeclaringSchema().getName().getFullName() + "." + _name.getName()); 95 96 return _name; 97 } 98 99 103 public void setTableOrView(boolean isTable) throws DBException { 104 this.isTable = isTable; 105 } 106 107 110 public boolean isTableOrView() { 111 return isTable; 112 } 113 114 119 public void changeColumns(ColumnElement[] elems,int action) throws DBException { 120 columns.changeElements(elems, action); 121 } 122 123 126 public ColumnElement[] getColumns() { 127 DBElement[] dbe = columns.getElements(); 128 return (ColumnElement[]) Arrays.asList(dbe).toArray(new ColumnElement[dbe.length]); 129 } 130 131 135 public ColumnElement getColumn(DBIdentifier name) { 136 return (ColumnElement) columns.find(name); 137 } 138 139 protected void initColumns(ConnectionProvider cp) { 140 if (cp != null) 141 try { 142 DatabaseMetaData dmd = cp.getDatabaseMetaData(); 143 String shortTableName = getName().getName(); 144 145 DDLBridge bridge = null; 146 if (IDEUtil.isIDERunning()) 147 bridge = new DDLBridge(cp.getConnection(), cp.getSchema(), dmd); 148 149 ResultSet rs; 150 if (bridge != null) { 151 bridge.getDriverSpecification().getColumns(shortTableName, "%"); 152 rs = bridge.getDriverSpecification().getResultSet(); 153 } else 154 rs = dmd.getColumns(cp.getConnection().getCatalog(), cp.getSchema(), shortTableName, "%"); 156 157 int sqlType; 158 String sqlTypeName; 159 String colName, colNull, colSize, colDec; 160 if (rs != null) { 161 HashMap rset = new HashMap(); 162 while (rs.next()) { 163 if (bridge != null) { 164 rset = bridge.getDriverSpecification().getRow(); 165 Object type = rset.get(new Integer (5)); 166 if (type != null) 167 sqlType = (new Integer ((String ) rset.get(new Integer (5)))).intValue(); 168 else 169 sqlType = 0; sqlTypeName = (String ) rset.get(new Integer (6)); 171 colName = (String ) rset.get(new Integer (4)); 172 colNull = (String ) rset.get(new Integer (11)); 173 colSize = (String ) rset.get(new Integer (7)); 174 colDec = (String ) rset.get(new Integer (9)); 175 rset.clear(); 176 } else { 177 sqlType = rs.getInt("DATA_TYPE"); sqlTypeName = rs.getString("TYPE_NAME").trim(); colName = rs.getString("COLUMN_NAME").trim(); colNull = Integer.toString(rs.getInt("NULLABLE")); colSize = rs.getString("COLUMN_SIZE"); colDec = rs.getString("DECIMAL_DIGITS"); } 184 185 String dbProductName = dmd.getDatabaseProductName().trim(); 186 if (dbProductName.indexOf("Oracle") != -1) { if (sqlType == 11 || ((sqlType == 1111) && sqlTypeName.startsWith("TIMESTAMP"))) 189 sqlType = Types.TIMESTAMP; 190 if ((sqlType == 1111) && sqlTypeName.equals("FLOAT")) sqlType = Types.DOUBLE; 192 if ((sqlType == 1111) && sqlTypeName.equals("BLOB")) sqlType = Types.BLOB; 194 if ((sqlType == 1111) && sqlTypeName.equals("CLOB")) sqlType = Types.CLOB; 196 if ((sqlType == 1111) && sqlTypeName.equals("NVARCHAR2")) sqlType = Types.CHAR; 198 } 199 if (dbProductName.indexOf("MySQL") != -1) { if ((sqlType == 1111) && sqlTypeName.equalsIgnoreCase("BIT")) sqlType = Types.BIT; 203 } 204 205 try { 208 new Integer (colSize); 209 } catch (NumberFormatException exc) { 210 colSize = Integer.toString(Integer.MAX_VALUE); 211 } 212 213 ColumnElementImpl cei = new ColumnElementImpl(colName, Integer.toString(sqlType), colNull, colSize, colDec); 214 ColumnElement ce = new ColumnElement(cei, (TableElement) element); 215 ColumnElement[] c = {ce}; 216 changeColumns(c, DBElement.Impl.ADD); 217 } 218 rs.close(); 219 } 220 } catch (Exception exc) { 221 if (Boolean.getBoolean("netbeans.debug.exceptions")) exc.printStackTrace(); 223 } 224 } 225 226 231 public void changeIndexes(IndexElement[] elems,int action) throws DBException { 232 indexes.changeElements(elems, action); 233 } 234 235 238 public IndexElement[] getIndexes() { 239 DBElement[] dbe = indexes.getElements(); 240 return (IndexElement[]) Arrays.asList(dbe).toArray(new IndexElement[dbe.length]); 241 } 242 243 247 public IndexElement getIndex(DBIdentifier name) { 248 return (IndexElement) indexes.find(name); 249 } 250 251 protected void initIndexes(ConnectionProvider cp) { 252 initIndexes(cp, null); 253 } 254 255 protected void initIndexes(ConnectionProvider cp, String tbl) { 256 if (cp != null) 257 try { 258 boolean unique; 259 DatabaseMetaData dmd = cp.getDatabaseMetaData(); 260 String shortTableName; 261 if (tbl == null) 262 shortTableName = getName().getName(); 263 else 264 shortTableName = tbl; 265 266 DDLBridge bridge = null; 267 if (IDEUtil.isIDERunning()) 268 bridge = new DDLBridge(cp.getConnection(), cp.getSchema(), dmd); 269 270 ResultSet rs; 271 if (bridge != null) { 272 bridge.getDriverSpecification().getIndexInfo(shortTableName, false, true); 273 rs = bridge.getDriverSpecification().getResultSet(); 274 } else 275 rs = dmd.getIndexInfo(cp.getConnection().getCatalog(), cp.getSchema(), shortTableName, false, true); 277 278 String name, columnName; 279 boolean unq; 280 LinkedList idxs = new LinkedList(); 281 if (rs != null) { 282 HashMap rset = new HashMap(); 283 String uniqueStr; 284 while (rs.next()) { 285 if (bridge != null) { 286 rset = bridge.getDriverSpecification().getRow(); 287 name = (String ) rset.get(new Integer (6)); 288 columnName = (String ) rset.get(new Integer (9)); 289 uniqueStr = (String ) rset.get(new Integer (4)); 290 if (uniqueStr == null || uniqueStr.equals("0") || uniqueStr.equalsIgnoreCase("false") || uniqueStr.equalsIgnoreCase("f")) 291 unq = false; 292 else 293 unq = true; 294 rset.clear(); 295 } else { 296 name = rs.getString("INDEX_NAME"); columnName = rs.getString("COLUMN_NAME"); if (columnName != null) 299 columnName = columnName.trim(); 300 unq = rs.getBoolean("NON_UNIQUE"); } 302 303 if (name == null) 304 continue; 305 else 306 name = name.trim(); 307 308 if (unq) 309 idxs.add(name + "." + columnName + ".false"); else 311 idxs.add(name + "." + columnName + ".true"); } 313 rs.close(); 314 } 315 316 String info; 317 int start, end; 318 for (int i = 0; i < idxs.size(); i++) { 319 info = idxs.get(i).toString(); 320 start = info.indexOf('.'); end = info.lastIndexOf('.'); name = info.substring(0, start); 323 if ((info.substring(end + 1)).equals("true")) unique = true; 325 else 326 unique = false; 327 328 if (indexes.find(DBIdentifier.create(name)) != null) 329 continue; 330 331 IndexElementImpl iei = new IndexElementImpl(this, name, unique); 332 IndexElement[] ie = {new IndexElement(iei, (TableElement) element)}; 333 iei.initColumns(idxs); 334 changeIndexes(ie, DBElement.Impl.ADD); 335 } 336 } catch (Exception exc) { 337 if (Boolean.getBoolean("netbeans.debug.exceptions")) exc.printStackTrace(); 339 } 340 } 341 342 347 public void changeKeys(KeyElement[] elems,int action) throws DBException { 348 keys.changeElements(elems, action); 349 } 350 351 354 public KeyElement[] getKeys() { 355 DBElement[] dbe = keys.getElements(); 356 return (KeyElement[]) Arrays.asList(dbe).toArray(new KeyElement[dbe.length]); 357 } 358 359 363 public KeyElement getKey(DBIdentifier name) { 364 return (KeyElement) keys.find(name); 365 } 366 367 368 protected void initKeys(ConnectionProvider cp) { 369 initKeys(cp, 0); 370 } 371 372 protected void initKeys(ConnectionProvider cp, int id) { 373 initKeys(cp, id, null); 376 } 377 378 protected void initKeys(ConnectionProvider cp, int id, String tbl) { 379 382 if (cp != null) 383 try { 384 String shortTableName; 385 if (tbl == null) 386 shortTableName = getName().getName(); 387 else 388 shortTableName = tbl; 389 390 DDLBridge bridge = null; 391 if (IDEUtil.isIDERunning()) 392 bridge = new DDLBridge(cp.getConnection(), cp.getSchema(), cp.getDatabaseMetaData()); 393 394 if (id != 1) 395 initFKs(cp, bridge, shortTableName); 396 if (id != 2) 397 initPK(cp, bridge, shortTableName); 398 } catch (Exception exc) { 399 if (Boolean.getBoolean("netbeans.debug.exceptions")) exc.printStackTrace(); 401 } 402 } 403 404 private void initFKs(ConnectionProvider cp, DDLBridge bridge, String shortTableName) throws SQLException, DBException { 405 ResultSet rs; 406 407 if (bridge != null) { 408 bridge.getDriverSpecification().getImportedKeys(shortTableName); 409 rs = bridge.getDriverSpecification().getResultSet(); 410 } else 411 rs = cp.getDatabaseMetaData().getImportedKeys(cp.getConnection().getCatalog(), cp.getSchema(), shortTableName); 412 413 String name, fkColName, pkTableName, pkColName, c1, c2, s1, s2; 414 if (rs != null) { 415 HashMap rset = new HashMap(); 416 while (rs.next()) { 417 if (bridge != null) { 418 rset = bridge.getDriverSpecification().getRow(); 419 420 c1 = (String ) rset.get(new Integer (1)); 422 s1 = (String ) rset.get(new Integer (2)); 423 c2 = (String ) rset.get(new Integer (5)); 424 s2 = (String ) rset.get(new Integer (6)); 425 426 name = (String ) rset.get(new Integer (12)); 427 fkColName = (String ) rset.get(new Integer (8)); 428 pkTableName = (String ) rset.get(new Integer (3)); 429 pkColName = (String ) rset.get(new Integer (4)); 430 rset.clear(); 431 } else { 432 c1 = rs.getString("PKTABLE_CAT"); s1 = rs.getString("PKTABLE_SCHEM"); c2 = rs.getString("FKTABLE_CAT"); s2 = rs.getString("FKTABLE_SCHEM"); 438 name = rs.getString("FK_NAME"); fkColName = rs.getString("FKCOLUMN_NAME").trim(); pkTableName = rs.getString("PKTABLE_NAME").trim(); pkColName = rs.getString("PKCOLUMN_NAME").trim(); } 443 444 if (comp(c1, c2)) { 445 if (! comp(s1, s2)) 446 continue; 447 } else 448 continue; 449 450 ColumnPairElement cpe; 451 452 if (name == null || name.trim().equals("")) 453 name = "GENERATED_FK_" + pkTableName; 454 else 455 name = name.trim(); 456 457 ColumnElement lce = getColumn(DBIdentifier.create(fkColName)); if (lce == null) continue; 460 461 SchemaElement se = ((TableElement) element).getDeclaringSchema(); 462 TableElement fte = se.getTable(DBIdentifier.create(pkTableName)); 463 ColumnElement fce = fte.getColumn(DBIdentifier.create(pkColName)); 464 ColumnPairElementImpl cpei = new ColumnPairElementImpl(lce.getName().getFullName() + ";" + fce.getName().getFullName()); cpe = new ColumnPairElement(cpei, lce, fce, (TableElement) element); 466 changeColumnPairs(new ColumnPairElement[] {cpe}, DBElement.Impl.ADD); 467 468 ForeignKeyElement fk = (ForeignKeyElement) keys.find(DBIdentifier.create(name)); 469 if (fk != null) 470 fk.addColumnPair(cpe); else { 472 ForeignKeyElementImpl fkei = new ForeignKeyElementImpl(this, name); 473 ForeignKeyElement fke = new ForeignKeyElement(fkei, (TableElement) element); 474 fke.addColumnPair(cpe); 475 changeKeys(new ForeignKeyElement[] {fke}, DBElement.Impl.ADD); 476 } 477 } 478 rs.close(); 479 } 480 } 481 482 private void initPK(ConnectionProvider cp, DDLBridge bridge, String shortTableName) throws SQLException, DBException { 483 ResultSet rs; 484 485 IndexElement[] iearr = getIndexes(); 486 if (iearr != null) { 487 for (int i = 0; i < iearr.length; i++) 488 if (iearr[i].isUnique()) { 489 UniqueKeyElementImpl ukei = new UniqueKeyElementImpl(iearr[i].getName().getName(), false); UniqueKeyElement uke = new UniqueKeyElement(ukei, (TableElement) element, iearr[i]); 491 uke.setColumns(iearr[i].getColumns()); 492 changeKeys(new UniqueKeyElement[]{uke}, DBElement.Impl.ADD); 493 } 494 495 UniqueKeyElement[] ukes = ((TableElement) element).getUniqueKeys(); 496 497 if (bridge != null) { 498 bridge.getDriverSpecification().getPrimaryKeys(shortTableName); 499 rs = bridge.getDriverSpecification().getResultSet(); 500 } else 501 rs = cp.getDatabaseMetaData().getPrimaryKeys(cp.getConnection().getCatalog(), cp.getSchema(), shortTableName); 502 503 TreeMap cols = new TreeMap(); 504 Object keySeq; 505 String colName; 506 if (rs != null) { 507 HashMap rset = new HashMap(); 508 while (rs.next()) { 509 if (bridge != null) { 510 rset = bridge.getDriverSpecification().getRow(); 511 keySeq = (Object ) rset.get(new Integer (5)); 512 colName = (String ) rset.get(new Integer (4)); 513 rset.clear(); 514 } else { 515 keySeq = rs.getObject("KEY_SEQ"); colName = rs.getString("COLUMN_NAME").trim(); } 518 519 cols.put(keySeq, colName); } 521 rs.close(); 522 } 523 524 boolean primary = false; 525 if (cols != null && cols.size() > 0) 526 primary = true; 527 528 if (primary) { 529 if (ukes == null || ukes.length == 0) { 530 533 String indexName = "primary_key_index"; int i = 1; 535 while (((TableElement)element).getIndex(DBIdentifier.create(indexName)) != null) { 536 indexName = indexName + i; 537 i++; 538 } 539 540 LinkedList idxs = new LinkedList(); 541 for (Iterator it = cols.values().iterator(); it.hasNext();) { 542 idxs.add(indexName + "." + it.next() + ".false"); } 545 546 IndexElementImpl iei = new IndexElementImpl(this, indexName, true); 547 IndexElement ie = new IndexElement(iei, (TableElement) element); 548 iei.initColumns(idxs); 549 changeIndexes(new IndexElement[] { ie }, DBElement.Impl.ADD); 550 551 UniqueKeyElementImpl ukei = new UniqueKeyElementImpl(ie.getName().getName(), true); 552 UniqueKeyElement uke = new UniqueKeyElement(ukei, (TableElement)element, ie); 553 uke.setColumns(ie.getColumns()); 554 changeKeys(new UniqueKeyElement[] { uke }, DBElement.Impl.ADD); 555 } else if (ukes.length == 1) 556 ukes[0].setPrimaryKey(primary); 557 else { 558 ColumnElement[] ces; 559 Object [] o = cols.values().toArray(); 560 boolean equals; 561 for (int i = 0; i < ukes.length; i++) { 562 ces = ukes[i].getColumns(); 563 if (ces.length != o.length) 564 continue; 565 else { 566 equals = true; 567 for (int j = 0; j < ces.length; j++) 568 if (! o[j].toString().equals(ces[j].getName().getName())) { 569 equals = false; 570 break; 571 } 572 if (equals) { 573 ukes[i].setPrimaryKey(primary); 574 break; 575 } 576 } 577 } 578 } 579 } 580 } 581 } 582 583 public ColumnPairElement[] getColumnPairs() { 584 DBElement[] dbe = columnPairs.getElements(); 585 return (ColumnPairElement[]) Arrays.asList(dbe).toArray(new ColumnPairElement[dbe.length]); 586 } 587 588 public ColumnPairElement getColumnPair(DBIdentifier name) { 589 ColumnPairElement cpe = (ColumnPairElement) columnPairs.find(name); 590 if (cpe == null) 591 try { 592 String fullName = name.getFullName(); 593 if (fullName == null) { 594 return null; 595 } 596 597 int pos = fullName.indexOf(";"); 598 String firstHalf = fullName.substring(0, pos); 599 String secondHalf = fullName.substring(pos + 1); 600 601 ColumnElement lce = getColumn(DBIdentifier.create(firstHalf)); 602 603 pos = secondHalf.lastIndexOf("."); 604 TableElement te = ((TableElement) element).getDeclaringSchema().getTable(DBIdentifier.create(secondHalf.substring(0, pos))); 605 if (te == null) 606 return null; 607 608 ColumnElement fce = te.getColumn(DBIdentifier.create(secondHalf)); 609 610 if (lce == null || fce == null) 611 return null; 612 613 ColumnPairElementImpl cpei = new ColumnPairElementImpl(lce.getName().getFullName() + ";" + fce.getName().getFullName()); cpe = new ColumnPairElement(cpei, lce, fce, (TableElement) element); 615 changeColumnPairs(new ColumnPairElement[] {cpe}, DBElement.Impl.ADD); 616 } catch (DBException exc) { 617 exc.printStackTrace(); 618 return null; 619 } 620 621 return cpe; 622 } 623 624 public void changeColumnPairs(ColumnPairElement[] pairs,int action) throws DBException { 625 columnPairs.changeElements(pairs, action); 626 } 627 628 629 631 635 public DBElementsCollection getColumnCollection () { 636 return columns; 637 } 638 639 644 public void setColumnCollection (DBElementsCollection collection) { 645 columns = collection; 646 } 647 648 652 public DBElementsCollection getIndexCollection () { 653 return indexes; 654 } 655 656 661 public void setIndexCollection (DBElementsCollection collection) { 662 indexes = collection; 663 } 664 665 669 public DBElementsCollection getKeyCollection () { 670 return keys; 671 } 672 673 678 public void setKeyCollection (DBElementsCollection collection) { 679 keys = collection; 680 } 681 682 } 683 | Popular Tags |