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