return supportedJOINs[JoinRowSet.LEFT_OUTER_JOIN]; } /** * Returns <code>true</code> if this <code>JoinRowSet</code> object supports * an SQL <code>RIGHT_OUTER_JOIN</code> and <code>false</code> if it does not. * * @return true is the RIGHT_OUTER_JOIN is supported; false otherwise */ public boolean supportsRightOuterJoin() { return supportedJOINs[JoinRowSet.RIGHT_OUTER_JOIN]; } /** * Returns <code>true</code> if this <code>JoinRowSet</code> object supports * an SQL <code>FULL_JOIN</code> and <code>false</code> if it does not. * * @return true is the FULL_JOIN is supported; false otherwise */ public boolean supportsFullJoin() { return supportedJOINs[JoinRowSet.FULL_JOIN]; } /** * Sets the type of SQL <code>JOIN</code> that this <code>JoinRowSet</code> * object will use. This method * allows an application to adjust the type of <code>JOIN</code> imposed * on tables contained within this <code>JoinRowSet</code> object and to do it * on the fly. The last <code>JOIN</code> type set determines the type of * <code>JOIN</code> to be performed. * <P> * Implementations should throw an <code>SQLException</code> if they do * not support the given <code>JOIN</code> type. * * @param type one of the standard <code>JoinRowSet</code> constants * indicating the type of <code>JOIN</code>. Must be one of the * following: * <code>JoinRowSet.CROSS_JOIN</code> * <code>JoinRowSet.INNER_JOIN</code> * <code>JoinRowSet.LEFT_OUTER_JOIN</code> * <code>JoinRowSet.RIGHT_OUTER_JOIN</code>, or * <code>JoinRowSet.FULL_JOIN</code> * @throws SQLException if an unsupported <code>JOIN</code> type is set */ public void setJoinType(int type) throws SQLException { // The join which governs the join of two rowsets is the last // join set, using setJoinType if (type >= JoinRowSet.CROSS_JOIN && type <= JoinRowSet.FULL_JOIN) { if (type != JoinRowSet.INNER_JOIN) { // This 'if' will be removed after all joins are implemented. throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notsupported").toString()); } else { Integer Intgr = Integer.valueOf(JoinRowSet.INNER_JOIN); vecJoinType.add(Intgr); } } else { throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notdefined").toString()); } //end if } /** * This checks for a match column for * whether it exists or not. * * @param <code>CachedRowSet</code> object whose match column needs to be checked. * @throws SQLException if MatchColumn is not set. */ private boolean checkforMatchColumn(Joinable rs) throws SQLException { int[] i = rs.getMatchColumnIndexes(); if (i.length <= 0) { return false; } return true; } /** * Internal initialization of <code>JoinRowSet</code>. */ private void initJOIN(CachedRowSet rowset) throws SQLException { try { CachedRowSetImpl cRowset = (CachedRowSetImpl)rowset; // Create a new CachedRowSet object local to this function. CachedRowSetImpl crsTemp = new CachedRowSetImpl(); RowSetMetaDataImpl rsmd = new RowSetMetaDataImpl(); /* The following 'if block' seems to be always going true. commenting this out for present if (!supportedJOINs[1]) { throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notsupported").toString()); } */ if (vecRowSetsInJOIN.isEmpty() ) { // implies first cRowset to be added to the Join // simply add this as a CachedRowSet. // Also add it to the class variable of type vector // do not need to check "type" of Join but it should be set. crsInternal = (CachedRowSetImpl)rowset.createCopy(); crsInternal.setMetaData((RowSetMetaDataImpl)cRowset.getMetaData()); // metadata will also set the MatchColumn. vecRowSetsInJOIN.add(cRowset); } else { // At this point we are ready to add another rowset to 'this' object // Check the size of vecJoinType and vecRowSetsInJoin // If nothing is being set, internally call setJoinType() // to set to JoinRowSet.INNER_JOIN. // For two rowsets one (valid) entry should be there in vecJoinType // For three rowsets two (valid) entries should be there in vecJoinType // Maintain vecRowSetsInJoin = vecJoinType + 1 if( (vecRowSetsInJOIN.size() - vecJoinType.size() ) == 2 ) { // we are going to add next rowset and setJoinType has not been set // recently, so set it to setJoinType() to JoinRowSet.INNER_JOIN. // the default join type setJoinType(JoinRowSet.INNER_JOIN); } else if( (vecRowSetsInJOIN.size() - vecJoinType.size() ) == 1 ) { // do nothing setjoinType() has been set by programmer } // Add the table names to the class variable of type vector. vecTableNames.add(crsInternal.getTableName()); vecTableNames.add(cRowset.getTableName()); // Now we have two rowsets crsInternal and cRowset which need // to be INNER JOIN'ED to form a new rowset // Compare table1.MatchColumn1.value1 == { table2.MatchColumn2.value1 // ... upto table2.MatchColumn2.valueN } // ... // Compare table1.MatchColumn1.valueM == { table2.MatchColumn2.value1 // ... upto table2.MatchColumn2.valueN } // // Assuming first rowset has M rows and second N rows. int rowCount2 = cRowset.size(); int rowCount1 = crsInternal.size(); // total columns in the new CachedRowSet will be sum of both -1 // (common column) int matchColumnCount = 0; for(int i=0; i< crsInternal.getMatchColumnIndexes().length; i++) { if(crsInternal.getMatchColumnIndexes()[i] != -1) ++ matchColumnCount; else break; } rsmd.setColumnCount (crsInternal.getMetaData().getColumnCount() + cRowset.getMetaData().getColumnCount() - matchColumnCount); crsTemp.setMetaData(rsmd); crsInternal.beforeFirst(); cRowset.beforeFirst(); for (int i = 1 ; i <= rowCount1 ; i++) { if(crsInternal.isAfterLast() ) { break; } if(crsInternal.next()) { cRowset.beforeFirst(); for(int j = 1 ; j <= rowCount2 ; j++) { if( cRowset.isAfterLast()) { break; } if(cRowset.next()) { boolean match = true; for(int k=0; k<matchColumnCount; k++) { if (!crsInternal.getObject( crsInternal.getMatchColumnIndexes()[k]).equals (cRowset.getObject(cRowset.getMatchColumnIndexes()[k]))) { match = false; break; } } if (match) { int p; int colc = 0; // reset this variable everytime you loop // re create a JoinRowSet in crsTemp object crsTemp.moveToInsertRow(); // create a new rowset crsTemp with data from first rowset for( p=1; p<=crsInternal.getMetaData().getColumnCount();p++) { match = false; for(int k=0; k<matchColumnCount; k++) { if (p == crsInternal.getMatchColumnIndexes()[k] ) { match = true; break; } } if ( !match ) { crsTemp.updateObject(++colc, crsInternal.getObject(p)); // column type also needs to be passed. rsmd.setColumnName (colc, crsInternal.getMetaData().getColumnName(p)); rsmd.setTableName(colc, crsInternal.getTableName()); rsmd.setColumnType(p, crsInternal.getMetaData().getColumnType(p)); rsmd.setAutoIncrement(p, crsInternal.getMetaData().isAutoIncrement(p)); rsmd.setCaseSensitive(p, crsInternal.getMetaData().isCaseSensitive(p)); rsmd.setCatalogName(p, crsInternal.getMetaData().getCatalogName(p)); rsmd.setColumnDisplaySize(p, crsInternal.getMetaData().getColumnDisplaySize(p)); rsmd.setColumnLabel(p, crsInternal.getMetaData().getColumnLabel(p)); rsmd.setColumnType(p, crsInternal.getMetaData().getColumnType(p)); rsmd.setColumnTypeName(p, crsInternal.getMetaData().getColumnTypeName(p)); rsmd.setCurrency(p,crsInternal.getMetaData().isCurrency(p) ); rsmd.setNullable(p, crsInternal.getMetaData().isNullable(p)); rsmd.setPrecision(p, crsInternal.getMetaData().getPrecision(p)); rsmd.setScale(p, crsInternal.getMetaData().getScale(p)); rsmd.setSchemaName(p, crsInternal.getMetaData().getSchemaName(p)); rsmd.setSearchable(p, crsInternal.getMetaData().isSearchable(p)); rsmd.setSigned(p, crsInternal.getMetaData().isSigned(p)); } else { // will happen only once, for that merged column pass // the types as OBJECT, if types not equal crsTemp.updateObject(++colc, crsInternal.getObject(p)); rsmd.setColumnName(colc, crsInternal.getMetaData().getColumnName(p)); rsmd.setTableName (colc, crsInternal.getTableName()+ "#"+ cRowset.getTableName()); rsmd.setColumnType(p, crsInternal.getMetaData().getColumnType(p)); rsmd.setAutoIncrement(p, crsInternal.getMetaData().isAutoIncrement(p)); rsmd.setCaseSensitive(p, crsInternal.getMetaData().isCaseSensitive(p)); rsmd.setCatalogName(p, crsInternal.getMetaData().getCatalogName(p)); rsmd.setColumnDisplaySize(p, crsInternal.getMetaData().getColumnDisplaySize(p)); rsmd.setColumnLabel(p, crsInternal.getMetaData().getColumnLabel(p)); rsmd.setColumnType(p, crsInternal.getMetaData().getColumnType(p)); rsmd.setColumnTypeName(p, crsInternal.getMetaData().getColumnTypeName(p)); rsmd.setCurrency(p,crsInternal.getMetaData().isCurrency(p) ); rsmd.setNullable(p, crsInternal.getMetaData().isNullable(p)); rsmd.setPrecision(p, crsInternal.getMetaData().getPrecision(p)); rsmd.setScale(p, crsInternal.getMetaData().getScale(p)); rsmd.setSchemaName(p, crsInternal.getMetaData().getSchemaName(p)); rsmd.setSearchable(p, crsInternal.getMetaData().isSearchable(p)); rsmd.setSigned(p, crsInternal.getMetaData().isSigned(p)); //don't do ++colc in the above statement } //end if } //end for // append the rowset crsTemp, with data from second rowset for(int q=1; q<= cRowset.getMetaData().getColumnCount();q++) { match = false; for(int k=0; k<matchColumnCount; k++) { if (q == cRowset.getMatchColumnIndexes()[k] ) { match = true; break; } } if ( !match ) { crsTemp.updateObject(++colc, cRowset.getObject(q)); rsmd.setColumnName (colc, cRowset.getMetaData().getColumnName(q)); rsmd.setTableName(colc, cRowset.getTableName()); /** * This will happen for a special case scenario. The value of 'p' * will always be one more than the number of columns in the first * rowset in the join. So, for a value of 'q' which is the number of * columns in the second rowset that participates in the join. * So decrement value of 'p' by 1 else `p+q-1` will be out of range. **/ //if((p+q-1) > ((crsInternal.getMetaData().getColumnCount()) + // (cRowset.getMetaData().getColumnCount()) - 1)) { // --p; //} rsmd.setColumnType(p+q-1, cRowset.getMetaData().getColumnType(q)); rsmd.setAutoIncrement(p+q-1, cRowset.getMetaData().isAutoIncrement(q)); rsmd.setCaseSensitive(p+q-1, cRowset.getMetaData().isCaseSensitive(q)); rsmd.setCatalogName(p+q-1, cRowset.getMetaData().getCatalogName(q)); rsmd.setColumnDisplaySize(p+q-1, cRowset.getMetaData().getColumnDisplaySize(q)); rsmd.setColumnLabel(p+q-1, cRowset.getMetaData().getColumnLabel(q)); rsmd.setColumnType(p+q-1, cRowset.getMetaData().getColumnType(q)); rsmd.setColumnTypeName(p+q-1, cRowset.getMetaData().getColumnTypeName(q)); rsmd.setCurrency(p+q-1,cRowset.getMetaData().isCurrency(q) ); rsmd.setNullable(p+q-1, cRowset.getMetaData().isNullable(q)); rsmd.setPrecision(p+q-1, cRowset.getMetaData().getPrecision(q)); rsmd.setScale(p+q-1, cRowset.getMetaData().getScale(q)); rsmd.setSchemaName(p+q-1, cRowset.getMetaData().getSchemaName(q)); rsmd.setSearchable(p+q-1, cRowset.getMetaData().isSearchable(q)); rsmd.setSigned(p+q-1, cRowset.getMetaData().isSigned(q)); } else { --p; } } crsTemp.insertRow(); crsTemp.moveToCurrentRow(); } else { // since not equa12 // so do nothing } //end if // bool1 = cRowset.next(); } } // end inner for //bool2 = crsInternal.next(); } } //end outer for crsTemp.setMetaData(rsmd); crsTemp.setOriginal(); // Now the join is done. // Make crsInternal = crsTemp, to be ready for next merge, if at all. int[] pCol = new int[matchColumnCount]; for(int i=0; i<matchColumnCount; i++) pCol[i] = crsInternal.getMatchColumnIndexes()[i]; crsInternal = (CachedRowSetImpl)crsTemp.createCopy(); // Because we add the first rowset as crsInternal to the // merged rowset, so pCol will point to the Match column. // until reset, am not sure we should set this or not(?) // if this is not set next inner join won't happen // if we explicitly do not set a set MatchColumn of // the new crsInternal. crsInternal.setMatchColumn(pCol); // Add the merged rowset to the class variable of type vector. crsInternal.setMetaData(rsmd); vecRowSetsInJOIN.add(cRowset); } //end if } catch(SQLException sqle) { // %%% Exception should not dump here: sqle.printStackTrace(); throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.initerror").toString() + sqle); } catch (Exception e) { e.printStackTrace(); throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.genericerr").toString() + e); } } /** * Return a SQL-like description of the <code>WHERE</code> clause being used * in a <code>JoinRowSet</code> object instance. An implementation can describe * the <code>WHERE</code> clause of the SQL <code>JOIN</code> by supplying a <code>SQL</code> * strings description of <code>JOIN</code> or provide a textual description to assist * applications using a <code>JoinRowSet</code>. * * @return whereClause a textual or SQL descripition of the logical * <code>WHERE</code> cluase used in the <code>JoinRowSet</code> instance * @throws SQLException if an error occurs in generating a representation * of the <code>WHERE</code> clause. */ public String getWhereClause() throws SQLException { String strWhereClause = "Select "; String whereClause; String tabName= ""; String strTabName = ""; int sz,cols; int j; CachedRowSetImpl crs; // get all the column(s) names from each rowset. // append them with their tablenames i.e. tableName.columnName // Select tableName1.columnName1,..., tableNameX.columnNameY // from tableName1,...tableNameX where // tableName1.(rowset1.getMatchColumnName()) == // tableName2.(rowset2.getMatchColumnName()) + "and" + // tableNameX.(rowsetX.getMatchColumnName()) == // tableNameZ.(rowsetZ.getMatchColumnName())); sz = vecRowSetsInJOIN.size(); for(int i=0;i<sz; i++) { crs = (CachedRowSetImpl)vecRowSetsInJOIN.get(i); cols = crs.getMetaData().getColumnCount(); tabName = tabName.concat(crs.getTableName()); strTabName = strTabName.concat(tabName+", "); j = 1; while(j<cols) { strWhereClause = strWhereClause.concat (tabName+"."+crs.getMetaData().getColumnName(j++)); strWhereClause = strWhereClause.concat(", "); } //end while } //end for // now remove the last "," strWhereClause = strWhereClause.substring (0, strWhereClause.lastIndexOf(",")); // Add from clause strWhereClause = strWhereClause.concat(" from "); // Add the table names. strWhereClause = strWhereClause.concat(strTabName); //Remove the last "," strWhereClause = strWhereClause.substring (0, strWhereClause.lastIndexOf(",")); // Add the where clause strWhereClause = strWhereClause.concat(" where "); // Get the match columns // rowset1.getMatchColumnName() == rowset2.getMatchColumnName() for(int i=0;i<sz; i++) { strWhereClause = strWhereClause.concat( ((CachedRowSetImpl)vecRowSetsInJOIN.get(i)).getMatchColumnNames()[0]); if(i%2!=0) { strWhereClause = strWhereClause.concat("="); } else { strWhereClause = strWhereClause.concat(" and"); } strWhereClause = strWhereClause.concat(" "); } return strWhereClause; } /** * Moves the cursor down one row from its current position and * returns <code>true</code> if the new cursor position is a * valid row. * The cursor for a new <code>ResultSet</code> object is initially * positioned before the first row. The first call to the method * <code>next</code> moves the cursor to the first row, making it * the current row; the second call makes the second row the * current row, and so on. * * <P>If an input stream from the previous row is open, it is * implicitly closed. The <code>ResultSet</code> object's warning * chain is cleared when a new row is read. * * @return <code>true</code> if the new current row is valid; * <code>false</code> if there are no more rows * @throws SQLException if an error occurs or * the cursor is not positioned in the rowset, before * the first row, or after the last row */ public boolean next() throws SQLException { return crsInternal.next(); } /** * Releases the current contents of this rowset, discarding outstanding * updates. The rowset contains no rows after the method * <code>release</code> is called. This method sends a * <code>RowSetChangedEvent</code> object to all registered listeners prior * to returning. * * @throws SQLException if an error occurs */ public void close() throws SQLException { crsInternal.close(); } /** * Reports whether the last column read was SQL <code>NULL</code>. * Note that you must first call the method <code>getXXX</code> * on a column to try to read its value and then call the method * <code>wasNull</code> to determine whether the value was * SQL <code>NULL</code>. * * @return <code>true</code> if the value in the last column read * was SQL <code>NULL</code>; <code>false</code> otherwise * @throws SQLException if an error occurs */ public boolean wasNull() throws SQLException { return crsInternal.wasNull(); } /** * Retrieves the value of the designated column in the current row * of this <code>JoinRowSetImpl</code> object as aLines 501–1000 of 4353. Previous lines Load more
return supportedJOINs[JoinRowSet.LEFT_OUTER_JOIN]; } /** * Returns <code>true</code> if this <code>JoinRowSet</code> object supports * an SQL <code>RIGHT_OUTER_JOIN</code> and <code>false</code> if it does not. * * @return true is the RIGHT_OUTER_JOIN is supported; false otherwise */ public boolean supportsRightOuterJoin() { return supportedJOINs[JoinRowSet.RIGHT_OUTER_JOIN]; } /** * Returns <code>true</code> if this <code>JoinRowSet</code> object supports * an SQL <code>FULL_JOIN</code> and <code>false</code> if it does not. * * @return true is the FULL_JOIN is supported; false otherwise */ public boolean supportsFullJoin() { return supportedJOINs[JoinRowSet.FULL_JOIN]; } /** * Sets the type of SQL <code>JOIN</code> that this <code>JoinRowSet</code> * object will use. This method * allows an application to adjust the type of <code>JOIN</code> imposed * on tables contained within this <code>JoinRowSet</code> object and to do it * on the fly. The last <code>JOIN</code> type set determines the type of * <code>JOIN</code> to be performed. * <P> * Implementations should throw an <code>SQLException</code> if they do * not support the given <code>JOIN</code> type. * * @param type one of the standard <code>JoinRowSet</code> constants * indicating the type of <code>JOIN</code>. Must be one of the * following: * <code>JoinRowSet.CROSS_JOIN</code> * <code>JoinRowSet.INNER_JOIN</code> * <code>JoinRowSet.LEFT_OUTER_JOIN</code> * <code>JoinRowSet.RIGHT_OUTER_JOIN</code>, or * <code>JoinRowSet.FULL_JOIN</code> * @throws SQLException if an unsupported <code>JOIN</code> type is set */ public void setJoinType(int type) throws SQLException { // The join which governs the join of two rowsets is the last // join set, using setJoinType if (type >= JoinRowSet.CROSS_JOIN && type <= JoinRowSet.FULL_JOIN) { if (type != JoinRowSet.INNER_JOIN) { // This 'if' will be removed after all joins are implemented. throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notsupported").toString()); } else { Integer Intgr = Integer.valueOf(JoinRowSet.INNER_JOIN); vecJoinType.add(Intgr); } } else { throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notdefined").toString()); } //end if } /** * This checks for a match column for * whether it exists or not. * * @param <code>CachedRowSet</code> object whose match column needs to be checked. * @throws SQLException if MatchColumn is not set. */ private boolean checkforMatchColumn(Joinable rs) throws SQLException { int[] i = rs.getMatchColumnIndexes(); if (i.length <= 0) { return false; } return true; } /** * Internal initialization of <code>JoinRowSet</code>. */ private void initJOIN(CachedRowSet rowset) throws SQLException { try { CachedRowSetImpl cRowset = (CachedRowSetImpl)rowset; // Create a new CachedRowSet object local to this function. CachedRowSetImpl crsTemp = new CachedRowSetImpl(); RowSetMetaDataImpl rsmd = new RowSetMetaDataImpl(); /* The following 'if block' seems to be always going true. commenting this out for present if (!supportedJOINs[1]) { throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notsupported").toString()); } */ if (vecRowSetsInJOIN.isEmpty() ) { // implies first cRowset to be added to the Join // simply add this as a CachedRowSet. // Also add it to the class variable of type vector // do not need to check "type" of Join but it should be set. crsInternal = (CachedRowSetImpl)rowset.createCopy(); crsInternal.setMetaData((RowSetMetaDataImpl)cRowset.getMetaData()); // metadata will also set the MatchColumn. vecRowSetsInJOIN.add(cRowset); } else { // At this point we are ready to add another rowset to 'this' object // Check the size of vecJoinType and vecRowSetsInJoin // If nothing is being set, internally call setJoinType() // to set to JoinRowSet.INNER_JOIN. // For two rowsets one (valid) entry should be there in vecJoinType // For three rowsets two (valid) entries should be there in vecJoinType // Maintain vecRowSetsInJoin = vecJoinType + 1 if( (vecRowSetsInJOIN.size() - vecJoinType.size() ) == 2 ) { // we are going to add next rowset and setJoinType has not been set // recently, so set it to setJoinType() to JoinRowSet.INNER_JOIN. // the default join type setJoinType(JoinRowSet.INNER_JOIN); } else if( (vecRowSetsInJOIN.size() - vecJoinType.size() ) == 1 ) { // do nothing setjoinType() has been set by programmer } // Add the table names to the class variable of type vector. vecTableNames.add(crsInternal.getTableName()); vecTableNames.add(cRowset.getTableName()); // Now we have two rowsets crsInternal and cRowset which need // to be INNER JOIN'ED to form a new rowset // Compare table1.MatchColumn1.value1 == { table2.MatchColumn2.value1 // ... upto table2.MatchColumn2.valueN } // ... // Compare table1.MatchColumn1.valueM == { table2.MatchColumn2.value1 // ... upto table2.MatchColumn2.valueN } // // Assuming first rowset has M rows and second N rows. int rowCount2 = cRowset.size(); int rowCount1 = crsInternal.size(); // total columns in the new CachedRowSet will be sum of both -1 // (common column) int matchColumnCount = 0; for(int i=0; i< crsInternal.getMatchColumnIndexes().length; i++) { if(crsInternal.getMatchColumnIndexes()[i] != -1) ++ matchColumnCount; else break; } rsmd.setColumnCount (crsInternal.getMetaData().getColumnCount() + cRowset.getMetaData().getColumnCount() - matchColumnCount); crsTemp.setMetaData(rsmd); crsInternal.beforeFirst(); cRowset.beforeFirst(); for (int i = 1 ; i <= rowCount1 ; i++) { if(crsInternal.isAfterLast() ) { break; } if(crsInternal.next()) { cRowset.beforeFirst(); for(int j = 1 ; j <= rowCount2 ; j++) { if( cRowset.isAfterLast()) { break; } if(cRowset.next()) { boolean match = true; for(int k=0; k<matchColumnCount; k++) { if (!crsInternal.getObject( crsInternal.getMatchColumnIndexes()[k]).equals (cRowset.getObject(cRowset.getMatchColumnIndexes()[k]))) { match = false; break; } } if (match) { int p; int colc = 0; // reset this variable everytime you loop // re create a JoinRowSet in crsTemp object crsTemp.moveToInsertRow(); // create a new rowset crsTemp with data from first rowset for( p=1; p<=crsInternal.getMetaData().getColumnCount();p++) { match = false; for(int k=0; k<matchColumnCount; k++) { if (p == crsInternal.getMatchColumnIndexes()[k] ) { match = true; break; } } if ( !match ) { crsTemp.updateObject(++colc, crsInternal.getObject(p)); // column type also needs to be passed. rsmd.setColumnName (colc, crsInternal.getMetaData().getColumnName(p)); rsmd.setTableName(colc, crsInternal.getTableName()); rsmd.setColumnType(p, crsInternal.getMetaData().getColumnType(p)); rsmd.setAutoIncrement(p, crsInternal.getMetaData().isAutoIncrement(p)); rsmd.setCaseSensitive(p, crsInternal.getMetaData().isCaseSensitive(p)); rsmd.setCatalogName(p, crsInternal.getMetaData().getCatalogName(p)); rsmd.setColumnDisplaySize(p, crsInternal.getMetaData().getColumnDisplaySize(p)); rsmd.setColumnLabel(p, crsInternal.getMetaData().getColumnLabel(p)); rsmd.setColumnType(p, crsInternal.getMetaData().getColumnType(p)); rsmd.setColumnTypeName(p, crsInternal.getMetaData().getColumnTypeName(p)); rsmd.setCurrency(p,crsInternal.getMetaData().isCurrency(p) ); rsmd.setNullable(p, crsInternal.getMetaData().isNullable(p)); rsmd.setPrecision(p, crsInternal.getMetaData().getPrecision(p)); rsmd.setScale(p, crsInternal.getMetaData().getScale(p)); rsmd.setSchemaName(p, crsInternal.getMetaData().getSchemaName(p)); rsmd.setSearchable(p, crsInternal.getMetaData().isSearchable(p)); rsmd.setSigned(p, crsInternal.getMetaData().isSigned(p)); } else { // will happen only once, for that merged column pass // the types as OBJECT, if types not equal crsTemp.updateObject(++colc, crsInternal.getObject(p)); rsmd.setColumnName(colc, crsInternal.getMetaData().getColumnName(p)); rsmd.setTableName (colc, crsInternal.getTableName()+ "#"+ cRowset.getTableName()); rsmd.setColumnType(p, crsInternal.getMetaData().getColumnType(p)); rsmd.setAutoIncrement(p, crsInternal.getMetaData().isAutoIncrement(p)); rsmd.setCaseSensitive(p, crsInternal.getMetaData().isCaseSensitive(p)); rsmd.setCatalogName(p, crsInternal.getMetaData().getCatalogName(p)); rsmd.setColumnDisplaySize(p, crsInternal.getMetaData().getColumnDisplaySize(p)); rsmd.setColumnLabel(p, crsInternal.getMetaData().getColumnLabel(p)); rsmd.setColumnType(p, crsInternal.getMetaData().getColumnType(p)); rsmd.setColumnTypeName(p, crsInternal.getMetaData().getColumnTypeName(p)); rsmd.setCurrency(p,crsInternal.getMetaData().isCurrency(p) ); rsmd.setNullable(p, crsInternal.getMetaData().isNullable(p)); rsmd.setPrecision(p, crsInternal.getMetaData().getPrecision(p)); rsmd.setScale(p, crsInternal.getMetaData().getScale(p)); rsmd.setSchemaName(p, crsInternal.getMetaData().getSchemaName(p)); rsmd.setSearchable(p, crsInternal.getMetaData().isSearchable(p)); rsmd.setSigned(p, crsInternal.getMetaData().isSigned(p)); //don't do ++colc in the above statement } //end if } //end for // append the rowset crsTemp, with data from second rowset for(int q=1; q<= cRowset.getMetaData().getColumnCount();q++) { match = false; for(int k=0; k<matchColumnCount; k++) { if (q == cRowset.getMatchColumnIndexes()[k] ) { match = true; break; } } if ( !match ) { crsTemp.updateObject(++colc, cRowset.getObject(q)); rsmd.setColumnName (colc, cRowset.getMetaData().getColumnName(q)); rsmd.setTableName(colc, cRowset.getTableName()); /** * This will happen for a special case scenario. The value of 'p' * will always be one more than the number of columns in the first * rowset in the join. So, for a value of 'q' which is the number of * columns in the second rowset that participates in the join. * So decrement value of 'p' by 1 else `p+q-1` will be out of range. **/ //if((p+q-1) > ((crsInternal.getMetaData().getColumnCount()) + // (cRowset.getMetaData().getColumnCount()) - 1)) { // --p; //} rsmd.setColumnType(p+q-1, cRowset.getMetaData().getColumnType(q)); rsmd.setAutoIncrement(p+q-1, cRowset.getMetaData().isAutoIncrement(q)); rsmd.setCaseSensitive(p+q-1, cRowset.getMetaData().isCaseSensitive(q)); rsmd.setCatalogName(p+q-1, cRowset.getMetaData().getCatalogName(q)); rsmd.setColumnDisplaySize(p+q-1, cRowset.getMetaData().getColumnDisplaySize(q)); rsmd.setColumnLabel(p+q-1, cRowset.getMetaData().getColumnLabel(q)); rsmd.setColumnType(p+q-1, cRowset.getMetaData().getColumnType(q)); rsmd.setColumnTypeName(p+q-1, cRowset.getMetaData().getColumnTypeName(q)); rsmd.setCurrency(p+q-1,cRowset.getMetaData().isCurrency(q) ); rsmd.setNullable(p+q-1, cRowset.getMetaData().isNullable(q)); rsmd.setPrecision(p+q-1, cRowset.getMetaData().getPrecision(q)); rsmd.setScale(p+q-1, cRowset.getMetaData().getScale(q)); rsmd.setSchemaName(p+q-1, cRowset.getMetaData().getSchemaName(q)); rsmd.setSearchable(p+q-1, cRowset.getMetaData().isSearchable(q)); rsmd.setSigned(p+q-1, cRowset.getMetaData().isSigned(q)); } else { --p; } } crsTemp.insertRow(); crsTemp.moveToCurrentRow(); } else { // since not equa12 // so do nothing } //end if // bool1 = cRowset.next(); } } // end inner for //bool2 = crsInternal.next(); } } //end outer for crsTemp.setMetaData(rsmd); crsTemp.setOriginal(); // Now the join is done. // Make crsInternal = crsTemp, to be ready for next merge, if at all. int[] pCol = new int[matchColumnCount]; for(int i=0; i<matchColumnCount; i++) pCol[i] = crsInternal.getMatchColumnIndexes()[i]; crsInternal = (CachedRowSetImpl)crsTemp.createCopy(); // Because we add the first rowset as crsInternal to the // merged rowset, so pCol will point to the Match column. // until reset, am not sure we should set this or not(?) // if this is not set next inner join won't happen // if we explicitly do not set a set MatchColumn of // the new crsInternal. crsInternal.setMatchColumn(pCol); // Add the merged rowset to the class variable of type vector. crsInternal.setMetaData(rsmd); vecRowSetsInJOIN.add(cRowset); } //end if } catch(SQLException sqle) { // %%% Exception should not dump here: sqle.printStackTrace(); throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.initerror").toString() + sqle); } catch (Exception e) { e.printStackTrace(); throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.genericerr").toString() + e); } } /** * Return a SQL-like description of the <code>WHERE</code> clause being used * in a <code>JoinRowSet</code> object instance. An implementation can describe * the <code>WHERE</code> clause of the SQL <code>JOIN</code> by supplying a <code>SQL</code> * strings description of <code>JOIN</code> or provide a textual description to assist * applications using a <code>JoinRowSet</code>. * * @return whereClause a textual or SQL descripition of the logical * <code>WHERE</code> cluase used in the <code>JoinRowSet</code> instance * @throws SQLException if an error occurs in generating a representation * of the <code>WHERE</code> clause. */ public String getWhereClause() throws SQLException { String strWhereClause = "Select "; String whereClause; String tabName= ""; String strTabName = ""; int sz,cols; int j; CachedRowSetImpl crs; // get all the column(s) names from each rowset. // append them with their tablenames i.e. tableName.columnName // Select tableName1.columnName1,..., tableNameX.columnNameY // from tableName1,...tableNameX where // tableName1.(rowset1.getMatchColumnName()) == // tableName2.(rowset2.getMatchColumnName()) + "and" + // tableNameX.(rowsetX.getMatchColumnName()) == // tableNameZ.(rowsetZ.getMatchColumnName())); sz = vecRowSetsInJOIN.size(); for(int i=0;i<sz; i++) { crs = (CachedRowSetImpl)vecRowSetsInJOIN.get(i); cols = crs.getMetaData().getColumnCount(); tabName = tabName.concat(crs.getTableName()); strTabName = strTabName.concat(tabName+", "); j = 1; while(j<cols) { strWhereClause = strWhereClause.concat (tabName+"."+crs.getMetaData().getColumnName(j++)); strWhereClause = strWhereClause.concat(", "); } //end while } //end for // now remove the last "," strWhereClause = strWhereClause.substring (0, strWhereClause.lastIndexOf(",")); // Add from clause strWhereClause = strWhereClause.concat(" from "); // Add the table names. strWhereClause = strWhereClause.concat(strTabName); //Remove the last "," strWhereClause = strWhereClause.substring (0, strWhereClause.lastIndexOf(",")); // Add the where clause strWhereClause = strWhereClause.concat(" where "); // Get the match columns // rowset1.getMatchColumnName() == rowset2.getMatchColumnName() for(int i=0;i<sz; i++) { strWhereClause = strWhereClause.concat( ((CachedRowSetImpl)vecRowSetsInJOIN.get(i)).getMatchColumnNames()[0]); if(i%2!=0) { strWhereClause = strWhereClause.concat("="); } else { strWhereClause = strWhereClause.concat(" and"); } strWhereClause = strWhereClause.concat(" "); } return strWhereClause; } /** * Moves the cursor down one row from its current position and * returns <code>true</code> if the new cursor position is a * valid row. * The cursor for a new <code>ResultSet</code> object is initially * positioned before the first row. The first call to the method * <code>next</code> moves the cursor to the first row, making it * the current row; the second call makes the second row the * current row, and so on. * * <P>If an input stream from the previous row is open, it is * implicitly closed. The <code>ResultSet</code> object's warning * chain is cleared when a new row is read. * * @return <code>true</code> if the new current row is valid; * <code>false</code> if there are no more rows * @throws SQLException if an error occurs or * the cursor is not positioned in the rowset, before * the first row, or after the last row */ public boolean next() throws SQLException { return crsInternal.next(); } /** * Releases the current contents of this rowset, discarding outstanding * updates. The rowset contains no rows after the method * <code>release</code> is called. This method sends a * <code>RowSetChangedEvent</code> object to all registered listeners prior * to returning. * * @throws SQLException if an error occurs */ public void close() throws SQLException { crsInternal.close(); } /** * Reports whether the last column read was SQL <code>NULL</code>. * Note that you must first call the method <code>getXXX</code> * on a column to try to read its value and then call the method * <code>wasNull</code> to determine whether the value was * SQL <code>NULL</code>. * * @return <code>true</code> if the value in the last column read * was SQL <code>NULL</code>; <code>false</code> otherwise * @throws SQLException if an error occurs */ public boolean wasNull() throws SQLException { return crsInternal.wasNull(); } /** * Retrieves the value of the designated column in the current row * of this <code>JoinRowSetImpl</code> object as a