etl.editor/src/org/netbeans/modules/sql/framework/model/visitors/SQLDBSynchronizationVisitor.java
author rnithya@netbeans.org
Wed, 23 Apr 2008 15:56:05 +0530
changeset 4205 2739cb16db12
parent 4203 1b8bf1d26fbe
child 4207 774fa5120845
permissions -rw-r--r--
Fix for 6682455
     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
     5  *
     6  * The contents of this file are subject to the terms of either the GNU
     7  * General Public License Version 2 only ("GPL") or the Common
     8  * Development and Distribution License("CDDL") (collectively, the
     9  * "License"). You may not use this file except in compliance with the
    10  * License. You can obtain a copy of the License at
    11  * http://www.netbeans.org/cddl-gplv2.html
    12  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    13  * specific language governing permissions and limitations under the
    14  * License.  When distributing the software, include this License Header
    15  * Notice in each file and include the License file at
    16  * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    17  * particular file as subject to the "Classpath" exception as provided
    18  * by Sun in the GPL Version 2 section of the License file that
    19  * accompanied this code. If applicable, add the following below the
    20  * License Header, with the fields enclosed by brackets [] replaced by
    21  * your own identifying information:
    22  * "Portions Copyrighted [year] [name of copyright owner]"
    23  *
    24  * Contributor(s):
    25  *
    26  * The Original Software is NetBeans. The Initial Developer of the Original
    27  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
    28  * Microsystems, Inc. All Rights Reserved.
    29  *
    30  * If you wish your version of this file to be governed by only the CDDL
    31  * or only the GPL Version 2, indicate your decision by adding
    32  * "[Contributor] elects to include this software in this distribution
    33  * under the [CDDL or GPL Version 2] license." If you do not indicate a
    34  * single choice of license, a recipient has the option to distribute
    35  * your version of this file under either the CDDL, the GPL Version 2 or
    36  * to extend the choice of license to its licensees as provided above.
    37  * However, if you add GPL Version 2 code and therefore, elected the GPL
    38  * Version 2 license, then the option applies only if the new code is
    39  * made subject to such option by the copyright holder.
    40  */
    41 package org.netbeans.modules.sql.framework.model.visitors;
    42 
    43 import com.sun.sql.framework.exception.DBSQLException;
    44 import java.sql.Connection;
    45 import java.util.Iterator;
    46 import java.util.List;
    47 import org.netbeans.modules.sql.framework.model.SQLDBColumn;
    48 import org.netbeans.modules.sql.framework.model.SQLDBTable;
    49 import org.netbeans.modules.sql.framework.model.SourceTable;
    50 import org.netbeans.modules.sql.framework.model.TargetTable;
    51 import org.netbeans.modules.sql.framework.model.ValidationInfo;
    52 import org.netbeans.modules.sql.framework.model.impl.SourceColumnImpl;
    53 import org.netbeans.modules.sql.framework.model.impl.TargetColumnImpl;
    54 import org.netbeans.modules.sql.framework.model.impl.ValidationInfoImpl;
    55 import org.netbeans.modules.sql.framework.ui.view.graph.MetaTableModel;
    56 import java.util.ArrayList;
    57 import net.java.hulp.i18n.Logger;
    58 import org.netbeans.modules.etl.logger.Localizer;
    59 import org.netbeans.modules.sql.framework.model.DBMetaDataFactory;
    60 import org.netbeans.modules.sql.framework.common.utils.DBExplorerUtil;
    61 import org.netbeans.modules.sql.framework.model.DBConnectionDefinition;
    62 import org.netbeans.modules.sql.framework.model.SQLDBModel;
    63 import org.netbeans.modules.sql.framework.model.impl.AbstractDBTable;
    64 
    65 
    66 
    67 /**
    68  * @author Ahimanikya Satapathy
    69  * @author Nithya Radhakrishnan
    70  * @version $Revision$
    71  */
    72 public class SQLDBSynchronizationVisitor {
    73 
    74     private static transient final Logger mLogger = Logger.getLogger(SQLDBSynchronizationVisitor.class.getName());
    75     private static transient final Localizer mLoc = Localizer.get();
    76     private class Table extends AbstractDBTable {
    77 
    78         public Table(String tname, String tcatalog, String tschema) {
    79             super(tname, tschema, tcatalog);
    80         }
    81     }
    82     
    83     public List<ValidationInfo> infoList = new ArrayList<ValidationInfo>();
    84 
    85     private void mergeUpdates(SQLDBColumn collabColumn, List newColumns, SQLDBTable table, MetaTableModel tableModel, boolean ignorePrecision) {
    86         SQLDBColumn newColumn = null;
    87         boolean columnMatched = true;
    88 
    89         for (Iterator itr = newColumns.iterator(); itr.hasNext();) {
    90             newColumn = (SQLDBColumn) itr.next();
    91             String newColName = newColumn.getName();
    92             String collabColName = collabColumn.getName();
    93 
    94             // check whether column name match
    95             columnMatched = (collabColName.compareTo(newColName) == 0);
    96 
    97             // If column name match
    98             if (columnMatched) {
    99                 // Check whether the column metadata is not matching
   100                 if (compareWith(collabColumn, newColumn, ignorePrecision) != 0) {
   101                     // *** UPDATE ***
   102                     copyFrom(newColumn, collabColumn, ignorePrecision);
   103                     tableModel.updateColumn(collabColName, collabColumn);
   104                     String desc = collabColumn.getQualifiedName() + " was updated from Database " + table.getParent().getModelName();
   105                     ValidationInfo vInfo = new ValidationInfoImpl(collabColumn, desc, ValidationInfo.VALIDATION_WARNING);
   106                     infoList.add(vInfo);
   107                 }
   108                 break;
   109             }
   110         }
   111 
   112         // column does not exist in the new table
   113         if (!columnMatched) {
   114             // *** DELETE *** the column
   115             table.deleteColumn(collabColumn.getName());
   116             tableModel.removeColumn(collabColumn);
   117             String desc = collabColumn.getQualifiedName() + " was deleted since it no longer exists in Database " + table.getParent().getModelName();
   118             ValidationInfo vInfo = new ValidationInfoImpl(collabColumn, desc, ValidationInfo.VALIDATION_WARNING);
   119             infoList.add(vInfo);
   120         }
   121     }
   122 
   123     public void copyFrom(SQLDBColumn source, SQLDBColumn target, boolean ignorePrecision) {
   124         target.setJdbcType(source.getJdbcType());
   125         if(!ignorePrecision) {
   126         target.setScale(source.getScale());
   127         target.setPrecision(source.getPrecision());
   128         }
   129         target.setOrdinalPosition(source.getOrdinalPosition());
   130         target.setPrimaryKey(source.isPrimaryKey());
   131         target.setForeignKey(source.isForeignKey());
   132         target.setNullable(source.isNullable());
   133     }
   134 
   135     private int compareWith(SQLDBColumn collabCol, SQLDBColumn newCol, boolean ignorePrecision) {
   136         // compare primary keys
   137         if (collabCol.isPrimaryKey() && !newCol.isPrimaryKey()) {
   138             return -1;
   139         } else if (!collabCol.isPrimaryKey() && newCol.isPrimaryKey()) {
   140             return 1;
   141         }
   142 
   143         // compare foreign keys
   144         if (collabCol.isForeignKey() && !newCol.isForeignKey()) {
   145             return -1;
   146         } else if (!collabCol.isForeignKey() && newCol.isForeignKey()) {
   147             return 1;
   148         }
   149 
   150         // compare type
   151         if (collabCol.getJdbcType() != newCol.getJdbcType()) {
   152             return -1;
   153         }
   154 
   155         if(!ignorePrecision) {
   156         // compare scale
   157         if (collabCol.getScale() != newCol.getScale()) {
   158             return -1;
   159         }
   160 
   161         // compare getPrecision
   162         if (collabCol.getPrecision() != newCol.getPrecision()) {
   163             return -1;
   164         }
   165         }
   166 
   167         // compare getOrdinalPosition
   168         if (collabCol.getOrdinalPosition() != newCol.getOrdinalPosition()) {
   169             return -1;
   170         }
   171 
   172         // compare isNullable
   173         if (collabCol.isNullable() != newCol.isNullable()) {
   174             return -1;
   175         }
   176 
   177         return 0;
   178     }
   179 
   180     private void mergeNewColumns(SQLDBColumn newColumn, List collabColumns, SQLDBTable table, MetaTableModel tableModel) {
   181         SQLDBColumn collabColumn = null;
   182         boolean columnMatched = true;
   183 
   184         for (Iterator itr = collabColumns.iterator(); itr.hasNext();) {
   185             collabColumn = (SQLDBColumn) itr.next();
   186             String newColName = newColumn.getName();
   187             String collabColName = collabColumn.getName();
   188 
   189             // check whether column name match
   190             columnMatched = (collabColName.compareTo(newColName) == 0);
   191 
   192             // If column name match
   193             if (columnMatched) {
   194                 break;
   195             }
   196         }
   197 
   198         if (!columnMatched) {
   199             SQLDBColumn col = null;
   200             if (table instanceof SourceTable) {
   201                 col = new SourceColumnImpl(newColumn);
   202             } else if (table instanceof TargetTable) {
   203                 col = new TargetColumnImpl(newColumn);
   204             }
   205             // *** ADD *** the column
   206             table.addColumn(col);
   207             tableModel.addColumn(col);
   208             String desc1 = "Found new column in Database -> " + table.getParent().getModelName() + col.getQualifiedName() + " was added";
   209             ValidationInfo vInfo1 = new ValidationInfoImpl(collabColumn, desc1, ValidationInfo.VALIDATION_INFO);
   210             infoList.add(vInfo1);
   211         }
   212     }
   213 
   214     public void mergeCollabTableWithDatabaseTable(SQLDBTable collabTable, MetaTableModel tableModel) throws DBSQLException, Exception {
   215         DBMetaDataFactory meta = new DBMetaDataFactory();
   216         DBConnectionDefinition connDef = ((SQLDBModel) collabTable.getParentObject()).getETLDBConnectionDefinition();
   217         Connection conn = DBExplorerUtil.createConnection(connDef.getConnectionProperties());
   218         if (conn == null) {
   219             return;
   220         }
   221         
   222         try {
   223             meta.connectDB(conn);
   224 
   225             AbstractDBTable ct = ((AbstractDBTable)collabTable);
   226             if (meta.isTableOrViewExist(ct.getResolvedCatalogName(), ct.getResolvedSchemaName(), ct.getResolvedTableName())) {
   227                 // Get the table from database
   228                 Table newTable = new Table(ct.getResolvedCatalogName(), ct.getResolvedSchemaName(), ct.getResolvedTableName());
   229                 meta.populateColumns(newTable);
   230 
   231                 List collabColumns = collabTable.getColumnList();
   232                 List newColumns = newTable.getColumnList();
   233 
   234                 for (Iterator itr = collabColumns.iterator(); itr.hasNext();) {
   235                     SQLDBColumn oldCol = (SQLDBColumn) itr.next();
   236                     int sqlTypeCode = oldCol.getJdbcType();
   237                     boolean ignorePrecision = false;
   238                     if ((sqlTypeCode == java.sql.Types.DATE || sqlTypeCode == java.sql.Types.TIME || sqlTypeCode == java.sql.Types.TIMESTAMP || sqlTypeCode == java.sql.Types.NUMERIC) && connDef.getDBType().equals(DBMetaDataFactory.AXION)) {
   239                         ignorePrecision = true;
   240                     }
   241                     mergeUpdates(oldCol, newColumns, collabTable, tableModel, ignorePrecision);
   242                 }
   243                 for (Iterator itr = newColumns.iterator(); itr.hasNext();) {
   244                     mergeNewColumns((SQLDBColumn) itr.next(), collabColumns, collabTable, tableModel);
   245                 }
   246 
   247             // TODO: XXXXX We also need to check PK, FK, Index modifications XXXXX
   248             } else {
   249                 String nbBundle1 = mLoc.t("BUND299: Table {0} is removed or renamed in Database",collabTable.getName());
   250                 String desc = nbBundle1.substring(15) + " " + connDef.getConnectionURL();
   251                 ValidationInfo vInfo = new ValidationInfoImpl(collabTable, desc, ValidationInfo.VALIDATION_ERROR);
   252                 infoList.add(vInfo);
   253                 return;
   254             }
   255         } finally {
   256            meta.disconnectDB();
   257         }
   258     }
   259 }