0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.modules.dbschema.jdbcimpl;
0043:
0044: import java.beans.PropertyChangeListener;
0045: import java.beans.PropertyChangeSupport;
0046: import java.sql.*;
0047: import java.util.*;
0048:
0049: import java.util.logging.Level;
0050: import java.util.logging.Logger;
0051: import org.netbeans.modules.dbschema.*;
0052: import org.netbeans.modules.dbschema.util.*;
0053:
0054: public class SchemaElementImpl extends DBElementImpl implements
0055: SchemaElement.Impl {
0056:
0057: private static Logger LOGGER = Logger
0058: .getLogger(SchemaElementImpl.class.getName());
0059:
0060: private DBElementsCollection tables;
0061:
0062: private DBIdentifier _schema;
0063: private DBIdentifier _catalog;
0064: private String _url;
0065: private String _username;
0066: private String _driver;
0067: private String _databaseProductName;
0068: private String _databaseProductVersion;
0069: private String _driverName;
0070: private String _driverVersion;
0071:
0072: private transient DatabaseMetaData dmd;
0073: private transient String catalog;
0074:
0075: private transient volatile boolean stop;
0076:
0077: public transient PropertyChangeSupport propertySupport = new PropertyChangeSupport(
0078: this );
0079:
0080: private transient int progress;
0081:
0082: /** Creates new SchemaElementImpl */
0083: public SchemaElementImpl() {
0084: this (null);
0085: }
0086:
0087: public SchemaElementImpl(ConnectionProvider cp) {
0088: tables = new DBElementsCollection(this , new TableElement[0]);
0089:
0090: //workaround for bug #4396371
0091: //http://andorra.eng:8080/cgi-bin/ws.exe/bugtraq/bug.hts?where=bugid_value%3D4396371
0092: Object hc = String.valueOf(tables.hashCode());
0093: while (DBElementsCollection.instances.contains(hc)) {
0094: tables = new DBElementsCollection(this , new TableElement[0]);
0095: hc = String.valueOf(tables.hashCode());
0096: }
0097: DBElementsCollection.instances.add(hc);
0098:
0099: if (cp != null) {
0100: try {
0101: String schema;
0102:
0103: dmd = cp.getDatabaseMetaData();
0104:
0105: _url = dmd.getURL();
0106: _username = dmd.getUserName();
0107: // schema = dmd.getUserName();
0108: schema = cp.getSchema();
0109: _schema = schema == null ? DBIdentifier.create("")
0110: : DBIdentifier.create(schema); //NOI18N
0111: catalog = cp.getConnection().getCatalog();
0112: _catalog = catalog == null ? DBIdentifier.create("")
0113: : DBIdentifier.create(catalog); //NOI18N
0114: _driver = cp.getDriver();
0115: _databaseProductName = dmd.getDatabaseProductName()
0116: .trim();
0117: _databaseProductVersion = dmd
0118: .getDatabaseProductVersion();
0119: _driverName = dmd.getDriverName();
0120: _driverVersion = dmd.getDriverVersion();
0121: } catch (Exception exc) {
0122: exc.printStackTrace();
0123: }
0124: }
0125:
0126: stop = false;
0127: }
0128:
0129: public void setName(DBIdentifier name) throws DBException {
0130: int pos;
0131: String fullName = name.getFullName();
0132:
0133: if (fullName == null) {
0134: fullName = name.getName();
0135: name.setFullName(fullName);
0136: }
0137:
0138: pos = fullName.lastIndexOf("/");
0139: if (pos != -1)
0140: name.setName(fullName.substring(pos + 1));
0141: else if (fullName.indexOf(".") != -1)
0142: name.setName(fullName);
0143:
0144: _name = name;
0145: }
0146:
0147: public DBIdentifier getName() {
0148: return _name;
0149: }
0150:
0151: /** Get the parsing status of the element.
0152: * This is a non-blocking operation.
0153: * @return one of {@link #STATUS_NOT}, {@link #STATUS_ERROR},
0154: * {@link #STATUS_PARTIAL}, or {@link #STATUS_OK}
0155: */
0156: public int getStatus() {
0157: //NOT IMPLEMENTED YET !!!
0158: return SchemaElement.STATUS_OK;
0159: }
0160:
0161: /** Set the schema name of this schema snapshot.
0162: * @param id the schema name, or <code>null</code>
0163: * @exception DBException if the operation cannot proceed
0164: */
0165: public void setSchema(DBIdentifier schema) throws DBException {
0166: _schema = schema;
0167: }
0168:
0169: /** Get the schema name of this schema snapshot.
0170: * @return the schema name, or <code>null</code> if this snapshot does
0171: * not have a schema name
0172: */
0173: public DBIdentifier getSchema() {
0174: return _schema;
0175: }
0176:
0177: /** Set the catalog name of this schema snapshot.
0178: * @param id the catalog name, or <code>null</code>
0179: * @exception DBException if the operation cannot proceed
0180: */
0181: public void setCatalog(DBIdentifier catalog) throws DBException {
0182: _catalog = catalog;
0183: }
0184:
0185: /** Get the catalog name of this schema snapshot.
0186: * @return the catalog name, or <code>null</code> if this snapshot does
0187: * not have a catalog name
0188: */
0189: public DBIdentifier getCatalog() {
0190: return _catalog;
0191: }
0192:
0193: /** Change the set of tables.
0194: * @param elems the tables to change
0195: * @param action one of {@link #ADD}, {@link #REMOVE}, or {@link #SET}
0196: * @exception DBException if the action cannot be handled
0197: */
0198: public void changeTables(TableElement[] elems, int action)
0199: throws DBException {
0200: tables.changeElements(elems, action);
0201: }
0202:
0203: /** Get all tables.
0204: * @return the tables
0205: */
0206: public TableElement[] getTables() {
0207: DBElement[] dbe = tables.getElements();
0208: return (TableElement[]) Arrays.asList(dbe).toArray(
0209: new TableElement[dbe.length]);
0210: }
0211:
0212: /** Find a table by name.
0213: * @param name the name for which to look
0214: * @return the table, or <code>null</code> if it does not exist
0215: */
0216: public TableElement getTable(DBIdentifier name) {
0217: return (TableElement) tables.find(name);
0218: }
0219:
0220: public void initTables(ConnectionProvider cp) {
0221: initTables(cp, null, null, false); //false = check tables references
0222: }
0223:
0224: public void initTables(ConnectionProvider cp, LinkedList t,
0225: LinkedList v) {
0226: initTables(cp, t, v, false); //false = check tables references
0227: }
0228:
0229: public void initTables(ConnectionProvider cp, LinkedList t,
0230: LinkedList v, boolean allTables) {
0231: if (cp != null)
0232: try {
0233: progress = 0;
0234: LinkedList tables = new LinkedList();
0235: LinkedList views = new LinkedList();
0236: LinkedList tablesTmp = new LinkedList();
0237: LinkedList viewsTmp = new LinkedList();
0238: // String user = dmd.getUserName().trim();
0239: String user = cp.getSchema();
0240: List recycleBinTables;
0241: ResultSet rs;
0242:
0243: DDLBridge bridge = null;
0244: if (IDEUtil.isIDERunning())
0245: bridge = new DDLBridge(cp.getConnection(), cp
0246: .getSchema(), dmd);
0247:
0248: // issue 76953: do not display tables from the Recycle Bin on Oracle 10 and higher
0249: if ("Oracle".equals(dmd.getDatabaseProductName())) { // NOI18N
0250: recycleBinTables = getOracleRecycleBinTables();
0251: } else {
0252: recycleBinTables = Collections.EMPTY_LIST;
0253: }
0254:
0255: //get the list of all tables and views
0256: if (bridge != null) {
0257: bridge.getDriverSpecification().getTables("%",
0258: new String[] { "TABLE" }); //NOI18N
0259: rs = bridge.getDriverSpecification().getResultSet();
0260: } else
0261: rs = dmd.getTables(catalog, user, "%",
0262: new String[] { "TABLE" }); //NOI18N
0263:
0264: if (rs != null) {
0265: while (rs.next()) {
0266: if (isStop()) {
0267: rs.close();
0268: return;
0269: }
0270:
0271: String tableTmp;
0272: if (bridge != null)
0273: tableTmp = (String) bridge
0274: .getDriverSpecification().getRow()
0275: .get(new Integer(3));
0276: else
0277: tableTmp = rs.getString("TABLE_NAME")
0278: .trim(); //NOI18N
0279:
0280: if (!recycleBinTables.contains(tableTmp)) {
0281: tablesTmp.add(tableTmp);
0282: }
0283: }
0284: rs.close();
0285: }
0286:
0287: rs = null;
0288: if (bridge != null)
0289: if (bridge.getDriverSpecification()
0290: .areViewsSupported()) {
0291: bridge.getDriverSpecification().getTables("%",
0292: new String[] { "VIEW" }); //NOI18N
0293: rs = bridge.getDriverSpecification()
0294: .getResultSet();
0295: } else if (MetaDataUtil.areViewsSupported(dmd
0296: .getDatabaseProductName()))
0297: rs = dmd.getTables(catalog, user, "%",
0298: new String[] { "VIEW" }); //NOI18N
0299:
0300: if (rs != null) {
0301: while (rs.next()) {
0302: if (isStop()) {
0303: rs.close();
0304: return;
0305: }
0306:
0307: if (bridge != null)
0308: viewsTmp.add((String) bridge
0309: .getDriverSpecification().getRow()
0310: .get(new Integer(3)));
0311: else
0312: viewsTmp.add(rs.getString("TABLE_NAME")
0313: .trim()); //NOI18N
0314: }
0315: rs.close();
0316: }
0317: //list of all tables and views collected
0318:
0319: if (t == null && v == null) {
0320: tables = tablesTmp;
0321: views = viewsTmp;
0322: } else {
0323: t = checkNames(t, tablesTmp);
0324: v = checkNames(v, viewsTmp);
0325:
0326: if (allTables)
0327: tables = t;
0328: else
0329: tables = checkReferences(t, bridge, user);
0330:
0331: views = v;
0332: }
0333:
0334: // the tables are included twice because for each table
0335: // the progress is incremented twice (once for the table itself and once for the keys)
0336: propertySupport.firePropertyChange("totalCount", null,
0337: new Integer(2 * tables.size() + views.size())); //NOI18N
0338:
0339: initTables(cp, tables, allTables);
0340: initViews(cp, views, bridge);
0341: } catch (Exception exc) {
0342: if (Boolean.getBoolean("netbeans.debug.exceptions")) // NOI18N
0343: exc.printStackTrace();
0344: }
0345: }
0346:
0347: private LinkedList checkNames(LinkedList toCheck, LinkedList names) {
0348: LinkedList result = new LinkedList();
0349:
0350: for (int i = 0; i < toCheck.size(); i++) {
0351: Object table = toCheck.get(i);
0352:
0353: if (names.contains(table))
0354: result.add(table);
0355: else if (Boolean.getBoolean("netbeans.debug.exceptions")) // NOI18N
0356: System.out.println("Cannot find " + table
0357: + " table in the database."); //NOI18N
0358: }
0359:
0360: return result;
0361: }
0362:
0363: private LinkedList checkReferences(LinkedList tables,
0364: DDLBridge bridge, String schema) throws SQLException {
0365: ResultSet rs;
0366: String pkSchema;
0367: String fkSchema;
0368: String refTable;
0369:
0370: for (int i = 0; i < tables.size(); i++) { //add all referenced tables
0371: if (bridge != null) {
0372: bridge.getDriverSpecification().getImportedKeys(
0373: tables.get(i).toString());
0374: rs = bridge.getDriverSpecification().getResultSet();
0375: } else
0376: rs = dmd.getImportedKeys(catalog, schema, tables.get(i)
0377: .toString());
0378:
0379: if (rs != null) {
0380: HashMap rset = new HashMap();
0381: String c1, c2, s1, s2;
0382: while (rs.next()) {
0383: if (bridge != null) {
0384: rset = bridge.getDriverSpecification().getRow();
0385:
0386: //test references between two schemas
0387: c1 = (String) rset.get(new Integer(1));
0388: s1 = (String) rset.get(new Integer(2));
0389: c2 = (String) rset.get(new Integer(5));
0390: s2 = (String) rset.get(new Integer(6));
0391:
0392: if (comp(c1, c2)) {
0393: if (!comp(s1, s2))
0394: continue;
0395: } else
0396: continue;
0397:
0398: pkSchema = (String) rset.get(new Integer(2));
0399: fkSchema = (String) rset.get(new Integer(6));
0400: if ((pkSchema == fkSchema)
0401: || (pkSchema.equals(fkSchema))) {
0402: refTable = (String) rset
0403: .get(new Integer(3));
0404: if (!tables.contains(refTable))
0405: tables.add(refTable);
0406: }
0407: rset.clear();
0408: } else {
0409: //test references between two schemas
0410: c1 = rs.getString("PKTABLE_CAT"); //NOI18N
0411: s1 = rs.getString("PKTABLE_SCHEM"); //NOI18N
0412: c2 = rs.getString("FKTABLE_CAT"); //NOI18N
0413: s2 = rs.getString("FKTABLE_SCHEM"); //NOI18N
0414:
0415: if (comp(c1, c2)) {
0416: if (!comp(s1, s2))
0417: continue;
0418: } else
0419: continue;
0420:
0421: pkSchema = rs.getString("PKTABLE_SCHEM"); //NOI18N
0422: if (pkSchema != null) {
0423: pkSchema = pkSchema.trim();
0424: }
0425: fkSchema = rs.getString("FKTABLE_SCHEM"); //NOI18N
0426: if (fkSchema != null) {
0427: fkSchema = fkSchema.trim();
0428: }
0429: if ((pkSchema == fkSchema)
0430: || (pkSchema.equals(fkSchema))) {
0431: refTable = rs.getString("PKTABLE_NAME")
0432: .trim(); //NOI18N
0433: if (!tables.contains(refTable))
0434: tables.add(refTable);
0435: }
0436: }
0437: }
0438: rs.close();
0439: }
0440: }
0441:
0442: return tables;
0443: }
0444:
0445: private void initTables(ConnectionProvider cp, LinkedList tables,
0446: boolean allTables) throws DBException {
0447: String name;
0448:
0449: for (int i = 0; i < tables.size(); i++) {
0450: if (isStop())
0451: return;
0452:
0453: name = tables.get(i).toString();
0454: propertySupport.firePropertyChange("tableName", null, name); //NOI18N
0455: TableElementImpl tei = new TableElementImpl(name);
0456: tei.setTableOrView(true);
0457: TableElement[] te = { new TableElement(tei,
0458: (SchemaElement) element) };
0459:
0460: tei.initColumns(cp);
0461: tei.initIndexes(cp);
0462: changeTables(te, DBElement.Impl.ADD);
0463:
0464: progress++;
0465: propertySupport.firePropertyChange("progress", null,
0466: new Integer(progress)); //NOI18N
0467: }
0468:
0469: TableElement te;
0470: String tableName;
0471: for (int i = 0; i < tables.size(); i++) {
0472: if (isStop())
0473: return;
0474:
0475: tableName = tables.get(i).toString();
0476: te = getTable(DBIdentifier.create(tableName));
0477: if (te != null) {
0478: propertySupport.firePropertyChange("FKt", null,
0479: tableName); //NOI18N
0480: int fkOption = allTables ? 3 : 0;
0481: ((TableElementImpl) te.getElementImpl()).initKeys(cp,
0482: fkOption, tableName);
0483: }
0484:
0485: progress++;
0486: propertySupport.firePropertyChange("progress", null,
0487: new Integer(progress)); //NOI18N
0488: }
0489: }
0490:
0491: private void initViews(ConnectionProvider cp, LinkedList views,
0492: DDLBridge bridge) throws DBException, SQLException {
0493: String name;
0494: ResultSet rs;
0495:
0496: for (int i = 0; i < views.size(); i++) {
0497: if (isStop())
0498: return;
0499:
0500: name = views.get(i).toString();
0501: propertySupport.firePropertyChange("viewName", null, name); //NOI18N
0502: TableElementImpl tei = new TableElementImpl(name);
0503: tei.setTableOrView(false);
0504: TableElement te = new TableElement(tei,
0505: (SchemaElement) element);
0506: tei.initColumns(cp);
0507:
0508: String database = dmd.getDatabaseProductName();
0509: if (database != null) { //could be null see bug 53887
0510: database = database.trim();
0511: } else {
0512: database = ""; //NOI18N
0513: }
0514: if (database.equalsIgnoreCase("Oracle")
0515: || database
0516: .equalsIgnoreCase("Microsoft SQL Server")) { //NOI18N
0517: propertySupport.firePropertyChange("FKv", null, name); //NOI18N
0518:
0519: ViewDependency vd = new ViewDependency(cp, cp
0520: .getSchema(), name);
0521: LinkedList tables = new LinkedList();
0522: LinkedList columns = new LinkedList();
0523:
0524: tables.clear();
0525: columns.clear();
0526: vd.constructPK();
0527: tables = vd.getTables();
0528: columns = vd.getColumns();
0529: if (!columns.isEmpty()) {
0530: boolean all = false;
0531: for (int k = 0; k < columns.size(); k++)
0532: //test if the view is created over all columns and try to eliminate agregation functions
0533: if (((String) columns.get(k)).trim().endsWith(
0534: "*")) {
0535: all = true;
0536: break;
0537: }
0538:
0539: boolean capture = true;
0540: LinkedList pkTables = new LinkedList();
0541: for (int j = 0; j < tables.size(); j++) {
0542: if (isStop())
0543: return;
0544:
0545: //compute PK
0546: if (bridge != null) {
0547: bridge.getDriverSpecification()
0548: .getPrimaryKeys(
0549: tables.get(j).toString());
0550: rs = bridge.getDriverSpecification()
0551: .getResultSet();
0552: } else
0553: rs = cp.getDatabaseMetaData()
0554: .getPrimaryKeys(
0555: cp.getConnection()
0556: .getCatalog(),
0557: cp.getSchema(),
0558: tables.get(j).toString());
0559:
0560: if (rs != null) {
0561: if (!all) {
0562: String colName;
0563: HashMap rset = new HashMap();
0564: while (rs.next()) {
0565: if (bridge != null) {
0566: rset = bridge
0567: .getDriverSpecification()
0568: .getRow();
0569: colName = (String) rset
0570: .get(new Integer(4));
0571: rset.clear();
0572: } else
0573: colName = rs.getString(
0574: "COLUMN_NAME").trim(); //NOI18N
0575:
0576: if (columns.contains(colName
0577: .toLowerCase())
0578: || columns
0579: .contains(tables
0580: .get(j)
0581: .toString()
0582: .toLowerCase()
0583: + "."
0584: + colName
0585: .toLowerCase()))
0586: continue;
0587: else {
0588: capture = false;
0589: break;
0590: }
0591: }
0592: }
0593:
0594: if (capture)
0595: pkTables.add(tables.get(j).toString());
0596:
0597: rs.close();
0598: }
0599: }
0600:
0601: if (capture)
0602: for (int j = 0; j < pkTables.size(); j++) {
0603: //capture PK
0604: tei.initIndexes(cp, pkTables.get(j)
0605: .toString());
0606: tei.initKeys(cp, 1, pkTables.get(j)
0607: .toString());
0608:
0609: LinkedList tempList = new LinkedList();
0610: UniqueKeyElement[] keys = te
0611: .getUniqueKeys();
0612: for (int k = 0; k < keys.length; k++)
0613: if (keys[k].isPrimaryKey())
0614: tempList.add(keys[k]);
0615:
0616: keys = new UniqueKeyElement[tempList.size()];
0617: for (int k = 0; k < tempList.size(); k++)
0618: keys[k] = (UniqueKeyElement) tempList
0619: .get(k);
0620: te.setKeys(keys);
0621:
0622: IndexElement[] indexes = new IndexElement[keys.length];
0623: for (int k = 0; k < keys.length; k++)
0624: indexes[k] = ((UniqueKeyElement) keys[k])
0625: .getAssociatedIndex();
0626: te.setIndexes(indexes);
0627: }
0628:
0629: //compound PKs
0630: if (te.getUniqueKeys().length > 1) {
0631: IndexElementImpl iei = new IndexElementImpl(
0632: tei, "GENERATED_PK_"
0633: + tei.getName().getName(), true);
0634: IndexElement[] ie = { new IndexElement(iei, te) };
0635: IndexElement[] ies = te.getIndexes();
0636: for (int j = 0; j < ies.length; j++)
0637: iei.changeColumns(ies[j].getColumns(),
0638: DBElement.Impl.ADD);
0639: te.setIndexes(ie);
0640:
0641: IndexElement ii = te.getIndexes()[0];
0642: UniqueKeyElementImpl ukei = new UniqueKeyElementImpl(
0643: ii.getName().getName(), true);
0644: UniqueKeyElement uke = new UniqueKeyElement(
0645: ukei, te, ii);
0646: uke.setColumns(ii.getColumns());
0647: tei.changeKeys(new UniqueKeyElement[] { uke },
0648: DBElement.Impl.SET);
0649: }
0650:
0651: //compute FKs
0652: LinkedList toCapture = new LinkedList();
0653: LinkedList validFKs = new LinkedList();
0654: LinkedList fkTables = new LinkedList();
0655: for (int j = 0; j < tables.size(); j++) {
0656: if (isStop())
0657: return;
0658:
0659: if (bridge != null) {
0660: bridge.getDriverSpecification()
0661: .getImportedKeys(
0662: tables.get(j).toString());
0663: rs = bridge.getDriverSpecification()
0664: .getResultSet();
0665: } else
0666: rs = cp.getDatabaseMetaData()
0667: .getImportedKeys(
0668: cp.getConnection()
0669: .getCatalog(),
0670: cp.getSchema(),
0671: tables.get(j).toString());
0672:
0673: if (rs != null) {
0674: HashMap rset = new HashMap();
0675: LinkedList local = new LinkedList();
0676: LinkedList ref = new LinkedList();
0677: LinkedList fk = new LinkedList();
0678: String fkName, c1, c2, s1, s2;
0679: while (rs.next()) {
0680: if (bridge != null) {
0681: rset = bridge
0682: .getDriverSpecification()
0683: .getRow();
0684:
0685: //test references between two schemas
0686: c1 = (String) rset.get(new Integer(
0687: 1));
0688: s1 = (String) rset.get(new Integer(
0689: 2));
0690: c2 = (String) rset.get(new Integer(
0691: 5));
0692: s2 = (String) rset.get(new Integer(
0693: 6));
0694:
0695: if (comp(c1, c2)) {
0696: if (!comp(s1, s2))
0697: continue;
0698: } else
0699: continue;
0700:
0701: fkName = (String) rset
0702: .get(new Integer(12));
0703: if (fkName == null)
0704: continue;
0705: else
0706: fkName = fkName.trim();
0707: // schemas = ((rset.get(new Integer(6)) == rset.get(new Integer(2))) || rset.get(new Integer(6)).equals(rset.get(new Integer(2)))) ? true : false;
0708: local
0709: .add(fkName
0710: + "."
0711: + ((String) rset
0712: .get(new Integer(
0713: 7)))
0714: + "."
0715: + ((String) rset
0716: .get(new Integer(
0717: 8)))); //NOI18N
0718: ref
0719: .add(fkName
0720: + "."
0721: + ((String) rset
0722: .get(new Integer(
0723: 3)))
0724: + "."
0725: + ((String) rset
0726: .get(new Integer(
0727: 4)))); //NOI18N
0728: if (!fk.contains(fkName))
0729: fk.add(fkName);
0730: rset.clear();
0731: } else {
0732: //test references between two schemas
0733: c1 = rs.getString("PKTABLE_CAT"); //NOI18N
0734: s1 = rs.getString("PKTABLE_SCHEM"); //NOI18N
0735: c2 = rs.getString("FKTABLE_CAT"); //NOI18N
0736: s2 = rs.getString("FKTABLE_SCHEM"); //NOI18N
0737:
0738: if (comp(c1, c2)) {
0739: if (!comp(s1, s2))
0740: continue;
0741: } else
0742: continue;
0743:
0744: fkName = rs.getString("FK_NAME"); //NOI18N
0745: if (fkName == null)
0746: continue;
0747: else
0748: fkName = fkName.trim();
0749: // schemas = ((rs.getString("FKTABLE_SCHEM") == rs.getString("PKTABLE_SCHEM")) || rs.getString("FKTABLE_SCHEM").equals(rs.getString("PKTABLE_SCHEM"))) ? true : false;
0750: local.add(fkName
0751: + "."
0752: + rs.getString(
0753: "FKTABLE_NAME")
0754: .trim()
0755: + "."
0756: + rs.getString(
0757: "FKCOLUMN_NAME")
0758: .trim()); //NOI18N
0759: ref.add(fkName
0760: + "."
0761: + rs.getString(
0762: "PKTABLE_NAME")
0763: .trim()
0764: + "."
0765: + rs.getString(
0766: "PKCOLUMN_NAME")
0767: .trim()); //NOI18N
0768: if (!fk.contains(fkName))
0769: fk.add(fkName);
0770: }
0771: }
0772: rs.close();
0773:
0774: String colName;
0775: for (int k = 0; k < fk.size(); k++) {
0776: fkName = fk.get(k).toString();
0777: for (int l = 0; l < local.size(); l++) {
0778: colName = local.get(l).toString();
0779: if (colName.startsWith(fkName))
0780: colName = colName
0781: .substring(
0782: colName
0783: .lastIndexOf(".") + 1)
0784: .toLowerCase();
0785: else
0786: continue;
0787:
0788: if (all
0789: || columns
0790: .contains(colName)
0791: || columns.contains(tables
0792: .get(j).toString()
0793: .toLowerCase()
0794: + "." + colName)) {
0795: continue;
0796: } else {
0797: fk.set(k, null);
0798: break;
0799: }
0800: }
0801:
0802: if (fk.get(k) != null)
0803: for (int l = 0; l < ref.size(); l++) {
0804: colName = ref.get(l).toString();
0805: if (colName.startsWith(fkName)) {
0806: colName = colName
0807: .substring(
0808: colName
0809: .indexOf(".") + 1,
0810: colName
0811: .lastIndexOf("."));
0812: if (getTable(DBIdentifier
0813: .create(colName)) == null)
0814: toCapture.add(colName);
0815: break;
0816: }
0817: }
0818: }
0819:
0820: String tblName = tables.get(j).toString();
0821: for (int k = 0; k < fk.size(); k++) {
0822: Object o = fk.get(k);
0823: if (o != null) {
0824: validFKs.add(o);
0825: if (!fkTables.contains(tblName))
0826: fkTables.add(tblName);
0827: }
0828: }
0829: }
0830: }
0831:
0832: initTables(cp, checkReferences(toCapture, bridge,
0833: cp.getSchema()), false);
0834:
0835: for (int j = 0; j < fkTables.size(); j++)
0836: tei.initKeys(cp, 2, fkTables.get(j).toString());
0837:
0838: LinkedList tempList = new LinkedList();
0839: ForeignKeyElement[] fke = te.getForeignKeys();
0840: UniqueKeyElement[] uke = te.getUniqueKeys();
0841: for (int j = 0; j < fke.length; j++)
0842: if (validFKs.contains(fke[j].getName()
0843: .getName()))
0844: tempList.add(fke[j]);
0845: KeyElement[] ke = new KeyElement[uke.length
0846: + tempList.size()];
0847: for (int j = 0; j < uke.length; j++)
0848: ke[j] = uke[j];
0849: int idx = uke.length;
0850: for (int j = 0; j < tempList.size(); j++)
0851: ke[j + idx] = (ForeignKeyElement) tempList
0852: .get(j);
0853:
0854: te.setKeys(ke);
0855:
0856: }
0857: }
0858:
0859: changeTables(new TableElement[] { te }, DBElement.Impl.ADD);
0860:
0861: progress++;
0862: propertySupport.firePropertyChange("progress", null,
0863: new Integer(progress)); //NOI18N
0864: }
0865: }
0866:
0867: private List getOracleRecycleBinTables() {
0868: List result = new ArrayList();
0869: try {
0870: if (dmd.getDatabaseMajorVersion() >= 10) {
0871: return Collections.EMPTY_LIST;
0872: }
0873:
0874: Statement stmt = dmd.getConnection().createStatement();
0875: try {
0876: ResultSet rs = stmt
0877: .executeQuery("SELECT OBJECT_NAME FROM RECYCLEBIN WHERE TYPE = 'TABLE'"); // NOI18N
0878: try {
0879: while (rs.next()) {
0880: result.add(rs.getString("OBJECT_NAME")); // NOI18N
0881: }
0882: } finally {
0883: rs.close();
0884: }
0885: } finally {
0886: stmt.close();
0887: }
0888: } catch (SQLException exc) {
0889: // Some older versions of Oracle driver throw an exception on
0890: // getDatabaseMajorVersion()
0891: LOGGER
0892: .log(
0893: Level.WARNING,
0894: "Some older versions of the Oracle "
0895: + " driver do not support getDatabaseMajorVersion(). "
0896: + " Setting recycle bin tables to an empty list.",
0897: exc); // NOI18N
0898:
0899: result = Collections.EMPTY_LIST;
0900: } catch (AbstractMethodError ame) {
0901: LOGGER
0902: .log(
0903: Level.WARNING,
0904: "Some older versions of the Oracle "
0905: + " driver do not support getDatabaseMajorVersion(). "
0906: + " Setting recycle bin tables to an empty list.",
0907: ame); // NOI18N
0908: result = Collections.EMPTY_LIST;
0909: }
0910: return result;
0911: }
0912:
0913: /** Getter for property url.
0914: * @return Value of property url.
0915: */
0916: public String getUrl() {
0917: return _url;
0918: }
0919:
0920: /** Setter for property url.
0921: * @param url New value of property url.
0922: */
0923: public void setUrl(String url) throws DBException {
0924: _url = url;
0925: }
0926:
0927: /** Getter for property username.
0928: * @return Value of property username.
0929: */
0930: public String getUsername() {
0931: return _username;
0932: }
0933:
0934: /** Setter for property username.
0935: * @param username New value of property username.
0936: */
0937: public void setUsername(String username) throws DBException {
0938: _username = username;
0939: }
0940:
0941: /** Getter for property driver.
0942: * @return Value of property driver.
0943: */
0944: public String getDriver() {
0945: return _driver;
0946: }
0947:
0948: /** Setter for property driver.
0949: * @param driver New value of property driver.
0950: */
0951: public void setDriver(String driver) {
0952: _driver = driver;
0953: }
0954:
0955: /** Getter for property databaseProductName.
0956: * @return Value of property databaseProductName.
0957: */
0958: public String getDatabaseProductName() {
0959: return _databaseProductName;
0960: }
0961:
0962: /** Setter for property databaseProductName.
0963: * @param databaseProductName New value of property databaseProductName.
0964: */
0965: public void setDatabaseProductName(String databaseProductName)
0966: throws DBException {
0967: _databaseProductName = databaseProductName;
0968: }
0969:
0970: /** Getter for property databaseProductVersion.
0971: * @return Value of property databaseProductVersion.
0972: */
0973: public String getDatabaseProductVersion() {
0974: return _databaseProductVersion;
0975: }
0976:
0977: /** Setter for property databaseProductVersion.
0978: * @param databaseProductVersion New value of property databaseProductVersion.
0979: */
0980: public void setDatabaseProductVersion(String databaseProductVersion)
0981: throws DBException {
0982: _databaseProductVersion = databaseProductVersion;
0983: }
0984:
0985: /** Getter for property driverName.
0986: * @return Value of property driverName.
0987: */
0988: public String getDriverName() {
0989: return _driverName;
0990: }
0991:
0992: /** Setter for property driverName.
0993: * @param driverName New value of property driverName.
0994: */
0995: public void setDriverName(String driverName) throws DBException {
0996: _driverName = driverName;
0997: }
0998:
0999: /** Getter for property driverVersion.
1000: * @return Value of property driverVersion.
1001: */
1002: public String getDriverVersion() {
1003: return _driverVersion;
1004: }
1005:
1006: /** Setter for property driverVersion.
1007: * @param driverVersion New value of property driverVersion.
1008: */
1009: public void setDriverVersion(String driverVersion)
1010: throws DBException {
1011: _driverVersion = driverVersion;
1012: }
1013:
1014: public boolean isStop() {
1015: return stop;
1016: }
1017:
1018: public void setStop(boolean stop) {
1019: this .stop = stop;
1020: }
1021:
1022: //========== property change support needed for progressbar ==========
1023: public void addPropertyChangeListener(PropertyChangeListener l) {
1024: propertySupport.addPropertyChangeListener(l);
1025: }
1026:
1027: public void removePropertyChangeListener(PropertyChangeListener l) {
1028: propertySupport.removePropertyChangeListener(l);
1029: }
1030:
1031: //=============== extra methods needed for xml archiver ==============
1032:
1033: /** Returns the table collection of this schema element. This method
1034: * should only be used internally and for cloning and archiving.
1035: * @return the table collection of this schema element
1036: */
1037: public DBElementsCollection getTableCollection() {
1038: return tables;
1039: }
1040:
1041: /** Set the table collection of this claschemass element to the supplied
1042: * collection. This method should only be used internally and for
1043: * cloning and archiving.
1044: * @param collection the table collection of this schema element
1045: */
1046: public void setTableCollection(DBElementsCollection collection) {
1047: tables = collection;
1048: }
1049: }
|