harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From telli...@apache.org
Subject svn commit: r646226 - in /harmony/enhanced/classlib/trunk/modules/sql/src: main/java/org/apache/harmony/sql/internal/nls/ main/java/org/apache/harmony/sql/internal/rowset/ test/java/org/apache/harmony/sql/tests/internal/rowset/
Date Wed, 09 Apr 2008 08:39:55 GMT
Author: tellison
Date: Wed Apr  9 01:39:51 2008
New Revision: 646226

URL: http://svn.apache.org/viewvc?rev=646226&view=rev
Log:
Apply patch HARMONY-5694 ([classlib][sql][rowset] - Implement inner join in JoinRowSetImpl)

Added:
    harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetJoinTest.java   (with props)
    harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetOtherTest.java   (with props)
Modified:
    harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties
    harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetImpl.java
    harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/JoinRowSetImpl.java
    harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetTest.java
    harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetTestCase.java

Modified: harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties?rev=646226&r1=646225&r2=646226&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties (original)
+++ harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/nls/messages.properties Wed Apr  9 01:39:51 2008
@@ -97,4 +97,3 @@
 rowset.34=Not set a match column
 rowset.35=Not a valid match olumn index
 rowset.36=Number of elements of two arrays don't equal
-rowset.37=The RowSet doesn't set the table name

Modified: harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetImpl.java?rev=646226&r1=646225&r2=646226&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetImpl.java (original)
+++ harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetImpl.java Wed Apr  9 01:39:51 2008
@@ -124,7 +124,7 @@
 
     private int[] keyCols;
 
-    private int columnCount;
+    protected int columnCount;
 
     private int deletedRowCount;
 
@@ -137,7 +137,7 @@
     // TODO deal with rowSetWarning
     private RowSetWarning rowSetWarning = new RowSetWarning();
 
-    private Class[] columnTypes;
+    protected Class[] columnTypes;
 
     private String[] matchColumnNames;
 
@@ -151,7 +151,7 @@
 
     private boolean isNotifyListener = true;
 
-    private static Map<Integer, Class<?>> TYPE_MAPPING = initialTypeMapping();
+    protected static Map<Integer, Class<?>> TYPE_MAPPING = initialTypeMapping();
 
     public static final String PROVIDER_ID = "Apache Harmony HYOptimisticProvider"; //$NON-NLS-1$
 

Modified: harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/JoinRowSetImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/JoinRowSetImpl.java?rev=646226&r1=646225&r2=646226&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/JoinRowSetImpl.java (original)
+++ harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/JoinRowSetImpl.java Wed Apr  9 01:39:51 2008
@@ -18,13 +18,17 @@
 
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
+import java.sql.Types;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 
 import javax.sql.RowSet;
 import javax.sql.RowSetMetaData;
 import javax.sql.rowset.CachedRowSet;
+import javax.sql.rowset.JdbcRowSet;
 import javax.sql.rowset.JoinRowSet;
 import javax.sql.rowset.Joinable;
 import javax.sql.rowset.RowSetMetaDataImpl;
@@ -43,6 +47,11 @@
 
     private int joinType;
 
+    private static String MERGED_COLUMN_NAME = "MergedCol"; //$NON-NLS-1$
+
+    // Whether the rows can be sorted using object in matched index.
+    private boolean isSortable;
+
     public JoinRowSetImpl() throws SyncFactoryException {
         super();
         initProperties();
@@ -76,7 +85,7 @@
             for (int i = 1; i <= getMetaData().getColumnCount(); i++) {
                 doCopyMetaData(rowSetMetaData, i, getMetaData(), i);
                 if (i == matchColIndexs.get(0).intValue()) {
-                    rowSetMetaData.setColumnName(i, "MergedCol"); //$NON-NLS-1$
+                    rowSetMetaData.setColumnName(i, MERGED_COLUMN_NAME);
                 }
             }
             int index = 0;
@@ -156,25 +165,59 @@
             throw new SQLException(Messages.getString("rowset.35")); //$NON-NLS-1$
         }
 
-        // TODO to be continue
-        rsList.add(rowset);
-        if (rsList.size() == 1) {
-            setMatchColumn(columnIdx);
-        }
-
+        int type = rowset.getMetaData().getColumnType(columnIdx);
         if (getMetaData() != null
-                && getMetaData().getColumnType(getMatchColumnIndexes()[0]) != rowset
-                        .getMetaData().getColumnType(columnIdx)) {
+                && getMetaData().getColumnType(getMatchColumnIndexes()[0]) != type) {
             setMetaData(null);
             rows = null;
+            // rowset.10=Data Type Mismatch
+            throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+        }
+
+        if (getMetaData() == null
+                && (type == Types.BINARY || type == Types.LONGVARBINARY
+                        || type == Types.VARBINARY || type == Types.BLOB
+                        || type == Types.CLOB || type == Types.ARRAY
+                        || type == Types.LONGVARCHAR
+                        || type == Types.JAVA_OBJECT || type == Types.OTHER || type == Types.NULL)) {
+            // rowset.10=Data Type Mismatch
             throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
         }
 
         composeMetaData(rowset.getMetaData(), columnIdx);
-        matchColIndexs.add(columnIdx);
 
-        // TODO join data
+        columnCount = getMetaData().getColumnCount();
+        // Reassign columnTypes.
+        columnTypes = new Class[columnCount];
+        for (int i = 1; i <= columnTypes.length; ++i) {
+            columnTypes[i - 1] = TYPE_MAPPING.get(Integer.valueOf(meta
+                    .getColumnType(i)));
+        }
+
+        matchColIndexs.add(Integer.valueOf(columnIdx));
+
+        if (rowset instanceof JdbcRowSet) {
+            CachedRowSet convertRowset = new CachedRowSetImpl();
+            convertRowset.populate(rowset);
+            rsList.add(convertRowset);
+        } else {
+            rsList.add(rowset);
+        }
 
+        if (rsList.size() == 1) {
+            initSortable();
+        }
+        try {
+            innerJoin();
+        } catch (CloneNotSupportedException e) {
+            SQLException sqlException = new SQLException();
+            sqlException.initCause(e);
+            throw sqlException;
+        }
+
+        if (rsList.size() == 1) {
+            setMatchColumn(columnIdx);
+        }
     }
 
     public void addRowSet(RowSet rowset, String columnName) throws SQLException {
@@ -256,7 +299,8 @@
         if (supportsJoinType(joinType)) {
             this.joinType = joinType;
         } else {
-            throw new SQLException("This type of join is not supported."); //$NON-NLS-1$
+            // rowset.38=This type of join is not supported
+            throw new SQLException(Messages.getString("rowset.38")); //$NON-NLS-1$
         }
     }
 
@@ -280,8 +324,8 @@
         return supportsJoinType(RIGHT_OUTER_JOIN);
     }
 
-    private boolean supportsJoinType(int joinType) {
-        if (joinType == INNER_JOIN) {
+    private boolean supportsJoinType(int type) {
+        if (type == INNER_JOIN) {
             return true;
         }
         return false;
@@ -291,4 +335,377 @@
         throw new NotImplementedException();
     }
 
+    /**
+     * Join the data with another CachedRowSet. It updates rows,
+     * currentRowIndex, currentRow and columnCount. It doesn't update its
+     * RowSetMetaData or any other status.
+     * 
+     * @throws SQLException
+     * @throws CloneNotSupportedException
+     */
+    private void innerJoin() throws SQLException, CloneNotSupportedException {
+        CachedRowSetImpl rowSetToAdd = (CachedRowSetImpl) rsList.get(rsList
+                .size() - 1);
+
+        // If it is the first RowSet added, then just copy the data of
+        // rowSetToAdd.
+        // Since here the RowSet has been added to rsList, so it is 2 to
+        // compared with, not 1.
+        if (rsList.size() < 2) {
+            // Create a new arrayList to store the copied data.
+            // Since the size will be the same with the rowSetToAdd, so
+            // initialing the list with this size will improve performance.
+            ArrayList<CachedRow> newRows = new ArrayList<CachedRow>(
+                    rowSetToAdd.rows.size());
+
+            // Make clones for all the CachedRows in rowSetToAdd, regardless of
+            // whether it is deleted.
+            for (int i = 0; i < rowSetToAdd.rows.size(); i++) {
+                newRows.add(rowSetToAdd.rows.get(i).createClone());
+            }
+
+            // Sets the rows and columnCount.
+            setRows(newRows, rowSetToAdd.columnCount);
+
+            // Set the currentRow and currentRowIndex.
+            currentRowIndex = rowSetToAdd.currentRowIndex;
+            if (currentRowIndex > 0 && currentRowIndex <= rows.size()) {
+                currentRow = rows.get(currentRowIndex - 1);
+            } else {
+                currentRow = null;
+            }
+        } else {
+            // Get the match index of itself and the rowSet to added.
+            int matchIndex = matchColIndexs.get(0).intValue();
+            // Here we can sure rsList.size() > 1
+            int matchIndexOfToAdd = matchColIndexs.get(rsList.size() - 1)
+                    .intValue();
+
+            // The comparator used to sort the rows of itself (When it can be
+            // sorted), and to compare
+            // the rows between these two rowSets.
+            CachedRowComparator comparator;
+
+            // If the rows can be sorted on the object of match index, call
+            // sortJoinRows.
+            // Otherwise call iterativeJoinRows.
+            if (isSortable()) {
+                comparator = new CachedRowComparator(matchIndex,
+                        matchIndexOfToAdd, true);
+                sortJoinRows(rowSetToAdd, matchIndex, matchIndexOfToAdd,
+                        comparator);
+            } else {
+                comparator = new CachedRowComparator(matchIndex,
+                        matchIndexOfToAdd, false);
+                iterativeJoinRows(rowSetToAdd, matchIndex, matchIndexOfToAdd,
+                        comparator);
+            }
+
+            // Set the curosr of rowSetToAdd to the last.
+            rowSetToAdd.last();
+
+            // Set the cursor of itself to beforeFirst.
+            beforeFirst();
+        }
+    }
+
+    private boolean isSortable() {
+        return isSortable;
+    }
+
+    private void initSortable() {
+        Class<?> clazz = columnTypes[matchColIndexs.get(0).intValue() - 1];
+        Class[] classes = clazz.getInterfaces();
+        isSortable = false;
+        for (Class<?> c : classes) {
+            if (c.equals(Comparable.class)) {
+                isSortable = true;
+                break;
+            }
+        }
+    }
+
+    private void iterativeJoinRows(CachedRowSetImpl rowSetToAdd,
+            int matchColumnIndex, int matchColumnIndexOfToAdd,
+            CachedRowComparator comparator) throws SQLException {
+        // The row from itself.
+        CachedRow row;
+        // The row from rowSet to add.
+        CachedRow rowToAdd;
+        // The row will be created to join the row and rowToAdd.
+        CachedRow newRow;
+
+        /*
+         * Create a new arrayList to store the copied data. Since the size will
+         * surely less then the min of the two rowSets, so initialing the list
+         * with half of the min will improve performance.
+         */
+        ArrayList<CachedRow> newRows = new ArrayList<CachedRow>(Math.min(rows
+                .size(), rowSetToAdd.rows.size()) / 2);
+
+        /*
+         * Computes the column count of rowSetToAdd, the result rowSet, the
+         * orignal rowSet.
+         */
+        int addedColumnCount = rowSetToAdd.getMetaData().getColumnCount();
+        int resultColumnCount = this.getMetaData().getColumnCount();
+
+        /*
+         * Since only one matched index is supported, and these two matched
+         * columns will merge to one column, so the original column count is
+         * just the minus of result comlumn count and added column count plus 1.
+         */
+        int originalColumnCount = resultColumnCount + 1 - addedColumnCount;
+
+        /*
+         * Iterates two rowsets, compare rowNum1 * rowNum2 times. If match,
+         * construct a new row, add it to the row list.
+         */
+        this.beforeFirst();
+        while (this.next()) {
+            row = this.getCurrentRow();
+            // If the value is null, just jump to next row.
+            // Since null won't match anything, even null.
+            if (row.getObject(matchColumnIndex) != null) {
+                rowSetToAdd.beforeFirst();
+                while (rowSetToAdd.next()) {
+                    rowToAdd = rowSetToAdd.getCurrentRow();
+                    if (comparator.compare(row, rowToAdd) == 0) {
+                        // It match, contruct a new row, add it to list.
+                        newRow = constructNewRow(row, rowToAdd,
+                                matchColumnIndex, matchColumnIndexOfToAdd,
+                                resultColumnCount, originalColumnCount);
+                        newRows.add(newRow);
+                    }
+                }
+            }
+        }
+
+        // Sets the rows and column count.
+        setRows(newRows, resultColumnCount);
+    }
+
+    private void sortJoinRows(CachedRowSetImpl rowSetToAdd,
+            int matchColumnIndex, int matchColumnIndexOfToAdd,
+            CachedRowComparator comparator) throws SQLException {
+        // The row from itself.
+        CachedRow row;
+        // The row from rowSet to add.
+        CachedRow rowToAdd;
+        // The row will be created to join the row and rowToAdd.
+        CachedRow newRow;
+
+        /*
+         * Create a new arrayList to store the copied data. Since the size will
+         * surely less then the min of the two rowSets, so initialing the list
+         * with half of the min will improve performance.
+         */
+        ArrayList<CachedRow> newRows = new ArrayList<CachedRow>(Math.min(rows
+                .size(), rowSetToAdd.rows.size()) / 2);
+
+        /*
+         * Computes the column count of rowSetToAdd, the result rowSet, the
+         * orignal rowSet.
+         */
+        int addedColumnCount = rowSetToAdd.getMetaData().getColumnCount();
+        int resultColumnCount = this.getMetaData().getColumnCount();
+
+        /*
+         * Since only one matched index is supported, and these two matched
+         * columns will merge to one column, so the original column count is
+         * just the minus of result comlumn count and added column count plus 1.
+         */
+        int originalColumnCount = resultColumnCount + 1 - addedColumnCount;
+
+        /*
+         * Sort the original rows. Set both the column to compared to the match
+         * index of original rows, since the comprasion will happened inside the
+         * orignal rows.
+         */
+        comparator.setFirstIndex(matchColumnIndex);
+        comparator.setSecondIndex(matchColumnIndex);
+        Collections.sort(rows, comparator);
+
+        /*
+         * Then comparator will be used to compare the object from two rowSets,
+         * so set firstIndex of comparator to match index of itself, and second
+         * index to match index of rowSet to add.
+         */
+        comparator.setFirstIndex(matchColumnIndex);
+        comparator.setSecondIndex(matchColumnIndexOfToAdd);
+
+        int position;
+        /*
+         * Iterates the rows of rowSetToAdd, find matched row in orignal rows
+         * using binary search.(It has been sorted).
+         */
+        rowSetToAdd.beforeFirst();
+        while (rowSetToAdd.next()) {
+            rowToAdd = rowSetToAdd.getCurrentRow();
+
+            /*
+             * If the value is null, just jump to next row. Since null won't
+             * match anything, even null.
+             */
+            if (rowToAdd.getObject(matchColumnIndexOfToAdd) == null) {
+                continue;
+            }
+
+            // Find the position of the matched row in original rows.
+            position = Collections.binarySearch(rows, rowToAdd, comparator);
+
+            // Not found, jump to next row.
+            if (position < 0) {
+                continue;
+            }
+
+            row = rows.get(position);
+            /*
+             * If row is deleted and showDeleted is false, it will not be
+             * joined.
+             */
+            if (getShowDeleted() || !row.isDelete()) {
+                // Contruct a new row, add it to list.
+                newRow = constructNewRow(row, rowToAdd, matchColumnIndex,
+                        matchColumnIndexOfToAdd, resultColumnCount,
+                        originalColumnCount);
+                newRows.add(newRow);
+
+                /*
+                 * Since there may be other rows also match, so we have to
+                 * examine the before positions and after positions until they
+                 * don't match. Remember, Collections.binarySearch does NOT
+                 * guarantee which row will be found if multiple element are
+                 * equal to the search value.
+                 */
+                for (int i = position - 1; i >= 0; i--) {
+                    row = rows.get(i);
+                    if (comparator.compare(row, rowToAdd) == 0) {
+                        newRow = constructNewRow(row, rowToAdd,
+                                matchColumnIndex, matchColumnIndexOfToAdd,
+                                resultColumnCount, originalColumnCount);
+                        newRows.add(newRow);
+                    } else {
+                        break;
+                    }
+                }
+
+                for (int i = position + 1; i < rows.size(); i++) {
+                    row = rows.get(i);
+                    if (comparator.compare(row, rowToAdd) == 0) {
+                        newRow = constructNewRow(row, rowToAdd,
+                                matchColumnIndex, matchColumnIndexOfToAdd,
+                                resultColumnCount, originalColumnCount);
+                        newRows.add(newRow);
+                    } else {
+                        break;
+                    }
+                }
+            }
+
+        }
+
+        // Sets the rows and column count.
+        setRows(newRows, resultColumnCount);
+    }
+
+    /**
+     * Construct a new CachedRow which will contain the data from both rows,
+     * excluding matched column, which will only appear once in the result row..
+     * 
+     * @param row
+     *            The first row to join.
+     * @param rowToAdd
+     *            The second row to join.
+     * @param matchColumnIndex
+     *            The match index of first row.
+     * @param matchColumnIndexOfToAdd
+     *            The match index of second row.
+     * @param resultColumnCount
+     *            The column count of the result row.
+     * @param originalColumnCount
+     *            The column count of original row.
+     * @return
+     */
+    protected CachedRow constructNewRow(CachedRow row, CachedRow rowToAdd,
+            int matchColumnIndex, int matchColumnIndexOfToAdd,
+            int resultColumnCount, int originalColumnCount) {
+        Object[] rowData;
+
+        rowData = new Object[resultColumnCount];
+
+        int i = 0;
+        for (; i < matchColumnIndex; i++) {
+            rowData[i] = row.getObject(i + 1);
+        }
+
+        for (; i < originalColumnCount; i++) {
+            rowData[i] = row.getObject(i + 1);
+        }
+
+        int j = 1;
+        for (; i < originalColumnCount + matchColumnIndexOfToAdd - 1; i++, j++) {
+            rowData[i] = rowToAdd.getObject(j);
+        }
+        for (; i < resultColumnCount; i++, j++) {
+            rowData[i] = rowToAdd.getObject(j + 1);
+        }
+        return new CachedRow(rowData);
+    }
+
+    private static class CachedRowComparator implements Comparator<CachedRow> {
+
+        private int firstIndex;
+
+        private int secondIndex;
+
+        private boolean isComparable;
+
+        public CachedRowComparator(int firstIndex, int secondIndex,
+                boolean isComparable) {
+            this.firstIndex = firstIndex;
+            this.secondIndex = secondIndex;
+            this.isComparable = isComparable;
+        }
+
+        public void setFirstIndex(int firstIndex) {
+            this.firstIndex = firstIndex;
+        }
+
+        public void setComparable(boolean isComparable) {
+            this.isComparable = isComparable;
+        }
+
+        public void setSecondIndex(int secondIndex) {
+            this.secondIndex = secondIndex;
+        }
+
+        public int compare(CachedRow object1, CachedRow object2) {
+            Object first = object1.getObject(firstIndex);
+            Object second = object2.getObject(secondIndex);
+
+            if (first == null && second == null) {
+                return 0;
+            }
+
+            if (first == null && second != null) {
+                return -1;
+            }
+
+            if (first != null && second == null) {
+                return 1;
+            }
+
+            if (isComparable) {
+                return ((Comparable<Object>) first).compareTo(second);
+            }
+
+            if (first.equals(second)) {
+                return 0;
+            }
+            return -1;
+
+        }
+
+    }
 }

Added: harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetJoinTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetJoinTest.java?rev=646226&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetJoinTest.java (added)
+++ harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetJoinTest.java Wed Apr  9 01:39:51 2008
@@ -0,0 +1,431 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.sql.tests.internal.rowset;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import javax.sql.rowset.CachedRowSet;
+
+public class JoinRowSetJoinTest extends JoinRowSetTestCase {
+
+    public void testJoin_DataEqual() throws Exception {
+        boolean dataEquals;
+        jrs.addRowSet(crset, 1);
+        dataEquals = dataEqualsIgnoreOrder(jrs, crset);
+        if (!dataEquals) {
+            fail("The data in jrs and crset should be equal.");
+        }
+
+        // Creates a new CachedRowSet from BOOKs
+        CachedRowSet crset2 = newNoInitialInstance();
+        rs = st.executeQuery("select * from BOOKS");
+        crset2.populate(rs);
+        jrs.addRowSet(crset2, 1);
+
+        CachedRowSet dbJoinCrset = newNoInitialInstance();
+        rs = st
+                .executeQuery("select USER_INFO.ID, USER_INFO.NAME, USER_INFO.BIGINT_T, USER_INFO.NUMERIC_T, USER_INFO.DECIMAL_T, "
+                        + "USER_INFO.SMALLINT_T, USER_INFO.FLOAT_T, USER_INFO.REAL_T, USER_INFO.DOUBLE_T, USER_INFO.DATE_T, USER_INFO.TIME_T, USER_INFO.TIMESTAMP_T, "
+                        + "BOOKS.SN, BOOKS.NAME"
+                        + " from USER_INFO, BOOKS "
+                        + "where USER_INFO.ID = BOOKS.AUTHORID");
+        dbJoinCrset.populate(rs);
+
+        dataEquals = dataEqualsIgnoreOrder(jrs, dbJoinCrset);
+        if (!dataEquals) {
+            fail("The data is jrs and dbJoinCrset should be equal.");
+        }
+
+        jrs = newJoinRowSet();
+        jrs.addRowSet(crset2, 1);
+        dataEquals = dataEqualsIgnoreOrder(crset2, jrs);
+        if (!dataEquals) {
+            fail("The data is jrs and crset2 should be equal.");
+        }
+
+        rs = st
+                .executeQuery("select BOOKS.AUTHORID, BOOKS.SN, BOOKS.NAME, USER_INFO.NAME, USER_INFO.BIGINT_T, USER_INFO.NUMERIC_T, USER_INFO.DECIMAL_T, "
+                        + "USER_INFO.SMALLINT_T, USER_INFO.FLOAT_T, USER_INFO.REAL_T, USER_INFO.DOUBLE_T, USER_INFO.DATE_T, USER_INFO.TIME_T, USER_INFO.TIMESTAMP_T "
+                        + " from USER_INFO, BOOKS "
+                        + "where USER_INFO.ID = BOOKS.AUTHORID");
+        dbJoinCrset = newNoInitialInstance();
+        dbJoinCrset.populate(rs);
+
+        jrs.addRowSet(crset, 1);
+        dataEquals = dataEqualsIgnoreOrder(jrs, dbJoinCrset);
+        if (!dataEquals) {
+            fail("The data is jrs and dbJoinCrset should be equal.");
+        }
+    }
+
+    public void testJoin_DataEqual_StringColumn() throws Exception {
+        boolean dataEquals;
+        jrs.addRowSet(crset, 2);
+
+        dataEquals = dataEqualsIgnoreOrder(jrs, crset);
+        if (!dataEquals) {
+            fail("The data in jrs and crset should be equal.");
+        }
+
+        // Creates a new CachedRowSet from BOOKs
+        CachedRowSet crset2 = newNoInitialInstance();
+        rs = st.executeQuery("select * from BOOKS");
+        crset2.populate(rs);
+
+        jrs.addRowSet(crset2, 3);
+
+        CachedRowSet dbJoinCrset = newNoInitialInstance();
+        rs = st
+                .executeQuery("select USER_INFO.ID, USER_INFO.NAME, USER_INFO.BIGINT_T, USER_INFO.NUMERIC_T, USER_INFO.DECIMAL_T, "
+                        + "USER_INFO.SMALLINT_T, USER_INFO.FLOAT_T, USER_INFO.REAL_T, USER_INFO.DOUBLE_T, USER_INFO.DATE_T, USER_INFO.TIME_T, USER_INFO.TIMESTAMP_T, "
+                        + "BOOKS.AUTHORID, BOOKS.SN"
+                        + " from USER_INFO, BOOKS "
+                        + "where USER_INFO.NAME = BOOKS.NAME");
+        dbJoinCrset.populate(rs);
+
+        dataEquals = dataEqualsIgnoreOrder(jrs, dbJoinCrset);
+        if (!dataEquals) {
+            fail("The data is jrs and dbJoinCrset should be equal.");
+        }
+
+        jrs = newJoinRowSet();
+        jrs.addRowSet(crset2, 3);
+        dataEquals = dataEqualsIgnoreOrder(crset2, jrs);
+        if (!dataEquals) {
+            fail("The data is jrs and crset2 should be equal.");
+        }
+
+        rs = st
+                .executeQuery("select BOOKS.AUTHORID, BOOKS.SN, BOOKS.NAME, USER_INFO.ID, USER_INFO.BIGINT_T, USER_INFO.NUMERIC_T, USER_INFO.DECIMAL_T, "
+                        + "USER_INFO.SMALLINT_T, USER_INFO.FLOAT_T, USER_INFO.REAL_T, USER_INFO.DOUBLE_T, USER_INFO.DATE_T, USER_INFO.TIME_T, USER_INFO.TIMESTAMP_T "
+                        + " from USER_INFO, BOOKS "
+                        + "where USER_INFO.NAME = BOOKS.NAME");
+        dbJoinCrset = newNoInitialInstance();
+        dbJoinCrset.populate(rs);
+
+        jrs.addRowSet(crset, 2);
+        dataEquals = dataEqualsIgnoreOrder(jrs, dbJoinCrset);
+        if (!dataEquals) {
+            fail("The data is jrs and dbJoinCrset should be equal.");
+        }
+    }
+
+    public void testJoin_DataEqual_MoreData() throws Exception {
+        insertMoreData(20);
+        rs = st.executeQuery("select * from USER_INFO");
+        crset = newNoInitialInstance();
+        crset.populate(rs);
+
+        boolean dataEquals;
+        jrs.addRowSet(crset, 1);
+        dataEquals = dataEqualsIgnoreOrder(jrs, crset);
+        if (!dataEquals) {
+            fail("The data in jrs and crset should be equal.");
+        }
+
+        // Creates a new CachedRowSet from BOOKs
+        CachedRowSet crset2 = newNoInitialInstance();
+        rs = st.executeQuery("select * from BOOKS");
+        crset2.populate(rs);
+
+        jrs.addRowSet(crset2, 1);
+
+        CachedRowSet dbJoinCrset = newNoInitialInstance();
+        rs = st
+                .executeQuery("select USER_INFO.ID, USER_INFO.NAME, USER_INFO.BIGINT_T, USER_INFO.NUMERIC_T, USER_INFO.DECIMAL_T, "
+                        + "USER_INFO.SMALLINT_T, USER_INFO.FLOAT_T, USER_INFO.REAL_T, USER_INFO.DOUBLE_T, USER_INFO.DATE_T, USER_INFO.TIME_T, USER_INFO.TIMESTAMP_T, "
+                        + "BOOKS.SN, BOOKS.NAME"
+                        + " from USER_INFO, BOOKS "
+                        + "where USER_INFO.ID = BOOKS.AUTHORID");
+        dbJoinCrset.populate(rs);
+
+        dataEquals = dataEqualsIgnoreOrder(jrs, dbJoinCrset);
+        if (!dataEquals) {
+            fail("The data is jrs and dbJoinCrset should be equal.");
+        }
+
+        jrs = newJoinRowSet();
+        jrs.addRowSet(crset2, 1);
+        dataEquals = dataEqualsIgnoreOrder(crset2, jrs);
+        if (!dataEquals) {
+            fail("The data is jrs and crset2 should be equal.");
+        }
+
+        rs = st
+                .executeQuery("select BOOKS.AUTHORID, BOOKS.SN, BOOKS.NAME, USER_INFO.NAME, USER_INFO.BIGINT_T, USER_INFO.NUMERIC_T, USER_INFO.DECIMAL_T, "
+                        + "USER_INFO.SMALLINT_T, USER_INFO.FLOAT_T, USER_INFO.REAL_T, USER_INFO.DOUBLE_T, USER_INFO.DATE_T, USER_INFO.TIME_T, USER_INFO.TIMESTAMP_T "
+                        + " from USER_INFO, BOOKS "
+                        + "where USER_INFO.ID = BOOKS.AUTHORID");
+        dbJoinCrset = newNoInitialInstance();
+        dbJoinCrset.populate(rs);
+
+        jrs.addRowSet(crset, 1);
+        dataEquals = dataEqualsIgnoreOrder(jrs, dbJoinCrset);
+        if (!dataEquals) {
+            fail("The data is jrs and dbJoinCrset should be equal.");
+        }
+
+    }
+
+    public void testJoin_DataEqual_NullData() throws Exception {
+        insertNullDataToBooks();
+        insertNullDataToUserInfo();
+
+        boolean dataEquals;
+        jrs.addRowSet(crset, 2);
+        dataEquals = dataEqualsIgnoreOrder(jrs, crset);
+        if (!dataEquals) {
+            fail("The data in jrs and crset should be equal.");
+        }
+
+        // Creates a new CachedRowSet from BOOKs
+        CachedRowSet crset2 = newNoInitialInstance();
+        rs = st.executeQuery("select * from BOOKS");
+        crset2.populate(rs);
+
+        jrs.addRowSet(crset2, 3);
+
+        CachedRowSet dbJoinCrset = newNoInitialInstance();
+        rs = st
+                .executeQuery("select USER_INFO.ID, USER_INFO.NAME, USER_INFO.BIGINT_T, USER_INFO.NUMERIC_T, USER_INFO.DECIMAL_T, "
+                        + "USER_INFO.SMALLINT_T, USER_INFO.FLOAT_T, USER_INFO.REAL_T, USER_INFO.DOUBLE_T, USER_INFO.DATE_T, USER_INFO.TIME_T, USER_INFO.TIMESTAMP_T, "
+                        + "BOOKS.AUTHORID, BOOKS.SN"
+                        + " from USER_INFO, BOOKS "
+                        + "where USER_INFO.NAME = BOOKS.NAME");
+        dbJoinCrset.populate(rs);
+
+        dataEquals = dataEqualsIgnoreOrderAndNullInR2(jrs, dbJoinCrset, 2);
+        if (!dataEquals) {
+            fail("The data is jrs and dbJoinCrset should be equal.");
+        }
+
+        jrs = newJoinRowSet();
+        jrs.addRowSet(crset2, 3);
+        dataEquals = dataEqualsIgnoreOrder(crset2, jrs);
+        if (!dataEquals) {
+            fail("The data is jrs and crset2 should be equal.");
+        }
+
+        rs = st
+                .executeQuery("select BOOKS.AUTHORID, BOOKS.SN, BOOKS.NAME, USER_INFO.ID, USER_INFO.BIGINT_T, USER_INFO.NUMERIC_T, USER_INFO.DECIMAL_T, "
+                        + "USER_INFO.SMALLINT_T, USER_INFO.FLOAT_T, USER_INFO.REAL_T, USER_INFO.DOUBLE_T, USER_INFO.DATE_T, USER_INFO.TIME_T, USER_INFO.TIMESTAMP_T "
+                        + " from USER_INFO, BOOKS "
+                        + "where USER_INFO.NAME = BOOKS.NAME");
+        dbJoinCrset = newNoInitialInstance();
+        dbJoinCrset.populate(rs);
+
+        jrs.addRowSet(crset, 2);
+        dataEquals = dataEqualsIgnoreOrderAndNullInR2(jrs, dbJoinCrset, 3);
+        if (!dataEquals) {
+            fail("The data is jrs and dbJoinCrset should be equal.");
+        }
+    }
+
+    public void testJoin_SameTable() throws Exception {
+        CachedRowSet crset2 = newNoInitialInstance();
+        rs = st.executeQuery("select * from BOOKS");
+        crset2.populate(rs);
+
+        CachedRowSet dbJoinCrset = newNoInitialInstance();
+        rs = st.executeQuery("select BOOKS1.AUTHORID, BOOKS1.SN, BOOKS1.NAME, "
+                + "BOOKS.AUTHORID, BOOKS.NAME"
+                + " from BOOKS as BOOKS1, BOOKS "
+                + "where BOOKS1.SN = BOOKS.SN");
+        dbJoinCrset.populate(rs);
+
+        jrs.addRowSet(crset2, "SN");
+        jrs.addRowSet(crset2, "SN");
+
+        boolean dataEquals = dataEqualsIgnoreOrder(jrs, dbJoinCrset);
+        if (!dataEquals) {
+            fail("The data is jrs and dbJoinCrset should be equal.");
+        }
+
+    }
+
+    public void testJoin_Unsortable() throws Exception {
+        addUnsortableToBooksTable();
+
+        CachedRowSet crset2 = newNoInitialInstance();
+        rs = st.executeQuery("select * from BOOKS");
+        crset2.populate(rs);
+
+        boolean dataEquals;
+        try {
+            jrs.addRowSet(crset2, 4);
+            if ("true".equals(System.getProperty("Testing Harmony"))) {
+                fail("Should throw SQLException here.(In harmony)");
+            } else {
+
+            }
+        } catch (SQLException e) {
+            if (!"true".equals(System.getProperty("Testing Harmony"))) {
+                fail("Should not throw SQLException here.(In RI)");
+            }
+        }
+        /*
+         * dataEquals = dataEqualsIgnoreOrder(jrs, crset2); if (!dataEquals) {
+         * fail("The data in jrs and crset2 should be equal."); }
+         */
+        try {
+            jrs.addRowSet(crset2, 4);
+            fail("Should throw SQLException here.");
+        } catch (SQLException e) {
+            // Expected.
+        }
+    }
+
+    // It proves that when the rowset is the first one added to the joinRowSet,
+    // it cursor doesn't move.
+    // Else, the cursor moves to the last one (not afterLast).
+    public void testJoin_OriginalCursorPosition() throws Exception {
+        // Create crset2.
+        rs = st.executeQuery("select * from BOOKS");
+        CachedRowSet crset2 = newNoInitialInstance();
+        crset2.populate(rs);
+
+        assertTrue(crset.isBeforeFirst());
+        jrs.addRowSet(crset, 1);
+        assertTrue(crset.isBeforeFirst());
+
+        crset.absolute(3);
+
+        jrs.addRowSet(crset, 1);
+        assertTrue(crset.isLast());
+
+        crset.last();
+        jrs.addRowSet(crset, 1);
+        assertTrue(crset.isLast());
+
+        crset.afterLast();
+        jrs.addRowSet(crset, 1);
+        assertTrue(crset.isLast());
+
+        crset.beforeFirst();
+        jrs.addRowSet(crset, 1);
+        assertTrue(crset.isLast());
+
+        crset.first();
+        crset2.beforeFirst();
+        jrs.addRowSet(crset2, 1);
+        assertTrue(crset2.isLast());
+        assertTrue(crset.isFirst());
+
+        jrs = newJoinRowSet();
+        crset.first();
+        jrs.addRowSet(crset, 1);
+        assertTrue(crset.isFirst());
+
+        jrs = newJoinRowSet();
+        crset.absolute(2);
+        jrs.addRowSet(crset, 1);
+        assertEquals(2, crset.getInt(1));
+    }
+
+    public void testJoin_CursorPosition() throws Exception {
+        rs = st.executeQuery("select * from BOOKS");
+        CachedRowSet crset2 = newNoInitialInstance();
+        crset2.populate(rs);
+
+        // TODO
+        // Tests when there is no rowSet.
+        // Not determined in harmony.
+        // assertTrue(jrs.isLast());
+        // assertTrue(jrs.isFirst());
+
+        // Tests when there is only one rowSet.
+        jrs.addRowSet(crset, 1);
+        assertTrue(jrs.isBeforeFirst());
+
+        jrs = newJoinRowSet();
+        crset.last();
+        jrs.addRowSet(crset, 1);
+        assertTrue(jrs.isLast());
+
+        // Tests where there are two rowset.
+        jrs = newJoinRowSet();
+        crset.last();
+        jrs.addRowSet(crset, 1);
+        assertTrue(jrs.last());
+        jrs.addRowSet(crset2, 1);
+        assertTrue(jrs.isBeforeFirst());
+
+        jrs = newJoinRowSet();
+        jrs.addRowSet(crset, 1);
+        crset2.absolute(1);
+        jrs.addRowSet(crset2, 1);
+        assertTrue(jrs.isBeforeFirst());
+
+        crset.last();
+        jrs = newJoinRowSet();
+        jrs.addRowSet(crset, 1);
+        assertTrue(jrs.isLast());
+        jrs.addRowSet(crset2, 1);
+        assertTrue(jrs.isBeforeFirst());
+
+        crset.last();
+        jrs = newJoinRowSet();
+        jrs.addRowSet(crset, 1);
+        assertTrue(jrs.isLast());
+        crset2.last();
+        jrs.addRowSet(crset2, 1);
+        assertTrue(jrs.isBeforeFirst());
+
+        crset.last();
+        jrs = newJoinRowSet();
+        jrs.addRowSet(crset, 1);
+        assertTrue(jrs.isLast());
+        crset2.absolute(1);
+        jrs.addRowSet(crset2, 1);
+        assertTrue(jrs.isBeforeFirst());
+    }
+
+    public void testJoin_Update() throws Exception {
+        rs = st.executeQuery("select * from BOOKS");
+        CachedRowSet crset2 = newNoInitialInstance();
+        crset2.populate(rs);
+
+        crset.first();
+        crset.updateString(2, "Updated");
+
+        jrs.addRowSet(crset, 1);
+        jrs.beforeFirst();
+        int count = 0;
+        while (jrs.next()) {
+            if (jrs.getInt(1) == 1) {
+                count++;
+                assertEquals("Updated", jrs.getString(2));
+            }
+        }
+        assertEquals(1, count);
+
+        crset2.first();
+        crset2.updateString(2, "Updated2");
+
+    }
+
+    protected int getVisibleSize(ResultSet rs) throws SQLException {
+        rs.beforeFirst();
+        int rowNum = 0;
+        while (rs.next()) {
+            rowNum++;
+        }
+        return rowNum;
+    }
+
+}

Propchange: harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetJoinTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetOtherTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetOtherTest.java?rev=646226&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetOtherTest.java (added)
+++ harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetOtherTest.java Wed Apr  9 01:39:51 2008
@@ -0,0 +1,207 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.sql.tests.internal.rowset;
+
+import java.sql.SQLException;
+
+import javax.sql.rowset.JoinRowSet;
+
+public class JoinRowSetOtherTest extends JoinRowSetTestCase {
+
+    /**
+     * @throws SQLException
+     * @tests javax.sql.rowset.JoinRowSet.supportsInnerJoin();
+     */
+    public void testSupportsInnerJoin() throws SQLException {
+        boolean isSupported = jrs.supportsInnerJoin();
+        assertTrue(isSupported);
+
+        jrs.addRowSet(crset, 1);
+        isSupported = jrs.supportsInnerJoin();
+        assertTrue(isSupported);
+    }
+
+    /**
+     * @throws SQLException
+     * @tests javax.sql.rowset.JoinRowSet.supportsCrossJoin();
+     */
+    public void testSupportsCrossJoin() throws SQLException {
+        boolean isSupported = jrs.supportsCrossJoin();
+        assertFalse(isSupported);
+
+        jrs.addRowSet(crset, 1);
+        isSupported = jrs.supportsCrossJoin();
+        assertFalse(isSupported);
+    }
+
+    /**
+     * @throws SQLException
+     * @tests javax.sql.rowset.JoinRowSet.supportsLeftOuterJoin();
+     */
+    public void testSupportsLeftOuterJoin() throws SQLException {
+        boolean isSupported = jrs.supportsLeftOuterJoin();
+        assertFalse(isSupported);
+
+        jrs.addRowSet(crset, 1);
+        isSupported = jrs.supportsLeftOuterJoin();
+        assertFalse(isSupported);
+    }
+
+    /**
+     * @throws SQLException
+     * @tests javax.sql.rowset.JoinRowSet.supportsRightOuterJoin();
+     */
+    public void testSupportsRightOuterJoin() throws SQLException {
+        boolean isSupported = jrs.supportsRightOuterJoin();
+        assertFalse(isSupported);
+
+        jrs.addRowSet(crset, 1);
+        isSupported = jrs.supportsRightOuterJoin();
+        assertFalse(isSupported);
+    }
+
+    /**
+     * @throws SQLException
+     * @tests javax.sql.rowset.JoinRowSet#supportsFullJoin();
+     */
+    public void testSupportsFullJoin() throws SQLException {
+        boolean isSupported = jrs.supportsFullJoin();
+        assertFalse(isSupported);
+
+        jrs.addRowSet(crset, 1);
+        isSupported = jrs.supportsFullJoin();
+        assertFalse(isSupported);
+    }
+
+    /**
+     * @tests java.sql.rowset.joinRowSet#setJoinType(int) and getJoinType();
+     * @throws SQLException
+     */
+    public void testSetJoinTypeAndGetJoinType() throws SQLException {
+        int joinType;
+
+        // Tests default join type.
+        if (System.getProperty("Testing Harmony") == "true") {
+            joinType = jrs.getJoinType();
+            assertEquals(JoinRowSet.INNER_JOIN, joinType);
+        } else {
+            try {
+                joinType = jrs.getJoinType();
+                fail("Should throw ArrayIndexOutOfBoundsException");
+            } catch (ArrayIndexOutOfBoundsException e) {
+                // Expected.
+            }
+        }
+
+        // Adds a rowset, then tests getJoinType().
+        jrs.addRowSet(crset, 1);
+
+        if (System.getProperty("Testing Harmony") == "true") {
+            joinType = jrs.getJoinType();
+            assertEquals(JoinRowSet.INNER_JOIN, joinType);
+        } else {
+            try {
+                joinType = jrs.getJoinType();
+                fail("Should throw ArrayIndexOutOfBoundsException");
+            } catch (ArrayIndexOutOfBoundsException e) {
+                // Expected.
+            }
+        }
+
+        // Tests setJoinType(CROSS_JOIN)
+        if (System.getProperty("Testing Harmony") == "true") {
+            try {
+                jrs.setJoinType(JoinRowSet.CROSS_JOIN);
+                fail("Should throw SQLException according to spec.");
+            } catch (SQLException e) {
+                // Expected.
+            }
+        } else {
+            try {
+                jrs.setJoinType(JoinRowSet.CROSS_JOIN);
+                fail("Should throw UnsupportedOperationException in RI");
+            } catch (UnsupportedOperationException e) {
+                // Expected
+            }
+        }
+
+        // Tests setJoinType(INNER_JOIN)
+        jrs.setJoinType(JoinRowSet.INNER_JOIN);
+        joinType = jrs.getJoinType();
+        assertEquals(JoinRowSet.INNER_JOIN, joinType);
+
+        // Tests setJoinType(FULL_JOIN)
+        if (System.getProperty("Testing Harmony") == "true") {
+            try {
+                jrs.setJoinType(JoinRowSet.FULL_JOIN);
+                fail("Should throw SQLException according to spec.");
+            } catch (SQLException e) {
+                // Expected.
+            }
+        } else {
+            try {
+                jrs.setJoinType(JoinRowSet.FULL_JOIN);
+                fail("Should throw UnsupportedOperationException in RI");
+            } catch (UnsupportedOperationException e) {
+                // Expected
+            }
+        }
+
+        // Tests setJoinType(LEFT_OUTER_JOIN)
+        if (System.getProperty("Testing Harmony") == "true") {
+            try {
+                jrs.setJoinType(JoinRowSet.LEFT_OUTER_JOIN);
+                fail("Should throw SQLException according to spec.");
+            } catch (SQLException e) {
+                // Expected.
+            }
+        } else {
+            try {
+                jrs.setJoinType(JoinRowSet.LEFT_OUTER_JOIN);
+                fail("Should throw UnsupportedOperationException in RI");
+            } catch (UnsupportedOperationException e) {
+                // Expected
+            }
+        }
+
+        // Tests setJoinType(RIGHT_OUTER_JOIN)
+        if (System.getProperty("Testing Harmony") == "true") {
+            try {
+                jrs.setJoinType(JoinRowSet.RIGHT_OUTER_JOIN);
+                fail("Should throw SQLException according to spec.");
+            } catch (SQLException e) {
+                // Expected.
+            }
+        } else {
+            try {
+                jrs.setJoinType(JoinRowSet.RIGHT_OUTER_JOIN);
+                fail("Should throw UnsupportedOperationException in RI");
+            } catch (UnsupportedOperationException e) {
+                // Expected
+            }
+        }
+
+        // Tests setJoinType(-1)
+        try {
+            jrs.setJoinType(-1);
+            fail("Should throw SQLException since -1 is a invalid type");
+        } catch (SQLException e) {
+            // Expected.
+        }
+    }
+
+}

Propchange: harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetOtherTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetTest.java?rev=646226&r1=646225&r2=646226&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetTest.java Wed Apr  9 01:39:51 2008
@@ -739,12 +739,9 @@
         crset.setTableName("BOOKS");
         jrs.addRowSet(crset);
         if ("true".equals(System.getProperty("Testing Harmony"))) {
-            try {
-                jrs.getRowSetNames();
-                fail("should throw SQLException");
-            } catch (SQLException e) {
-                // expected
-            }
+            assertEquals(2, jrs.getRowSetNames().length);
+            assertEquals("USER_INFO", jrs.getRowSetNames()[0]);
+            assertEquals("BOOKS", jrs.getRowSetNames()[1]);
         } else {
             try {
                 jrs.getRowSetNames();

Modified: harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetTestCase.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetTestCase.java?rev=646226&r1=646225&r2=646226&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetTestCase.java (original)
+++ harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/JoinRowSetTestCase.java Wed Apr  9 01:39:51 2008
@@ -17,7 +17,9 @@
 
 package org.apache.harmony.sql.tests.internal.rowset;
 
+import java.sql.PreparedStatement;
 import java.sql.SQLException;
+
 import javax.sql.RowSet;
 import javax.sql.rowset.FilteredRowSet;
 import javax.sql.rowset.JdbcRowSet;
@@ -31,6 +33,7 @@
     public void setUp() throws Exception {
         super.setUp();
         createBookTable();
+        createNewTable();
         jrs = newJoinRowSet();
     }
 
@@ -72,6 +75,68 @@
                 .executeUpdate("insert into BOOKS(AUTHORID,SN,NAME) values (5,'sn5-1','test5')");
     }
 
+    public void insertNullDataToBooks() throws Exception {
+        st = conn.createStatement();
+        st
+                .executeUpdate("insert into BOOKS(AUTHORID,SN,NAME) values (1,'sn1-1','null')");
+
+        st
+                .executeUpdate("insert into BOOKS(AUTHORID,SN,NAME) values (2,'sn1-2','null')");
+        st
+
+                .executeUpdate("insert into BOOKS(AUTHORID,SN,NAME) values (3,'sn4-1','null')");
+
+    }
+
+    public void addUnsortableToBooksTable() throws Exception {
+        st = conn.createStatement();
+        st.executeUpdate("alter table BOOKS add VARCHAR_FOR_BIT_T VARCHAR(100) FOR BIT DATA");
+        
+        String insertSQL = "INSERT INTO BOOKS(AUTHORID, SN, NAME, VARCHAR_FOR_BIT_T) VALUES(?, ?, ?, ?)";
+        PreparedStatement preStmt = conn.prepareStatement(insertSQL);
+
+        byte[] bs = new byte[] { 1, 2, 3, 4, 5 };
+        preStmt.setInt(1, 10);
+        preStmt.setString(2, "sn10");
+        preStmt.setString(3, "test10");
+        preStmt.setBytes(4, bs);
+        preStmt.executeUpdate();
+        
+        byte[] bs2 = new byte[] { 2, 3, 4, 5, 6, 7};
+        
+        preStmt.setInt(1, 11);
+        preStmt.setString(2, "sn11");
+        preStmt.setString(3, "test11");
+        preStmt.setBytes(4, bs2);
+        preStmt.executeUpdate();
+        
+        preStmt.setInt(1, 12);
+        preStmt.setString(2, "sn12");
+        preStmt.setString(3, "test12");
+        preStmt.setBytes(4, bs);
+        preStmt.executeUpdate();
+        
+        preStmt.setInt(1, 13);
+        preStmt.setString(2, "sn13");
+        preStmt.setString(3, "test13");
+        preStmt.setBytes(4, bs2);
+        preStmt.executeUpdate();
+        
+        
+        if (preStmt != null) {
+            preStmt.close();
+        }
+    }
+    
+    public void insertNullDataToUserInfo() throws Exception {
+        st = conn.createStatement();
+        st
+                .executeUpdate("insert into USER_INFO(ID,NAME) values (235,'null')");
+        st
+                .executeUpdate("insert into USER_INFO(ID,NAME) values (357,'null')");
+ 
+    }
+
     protected JoinRowSet newJoinRowSet() throws Exception {
         JoinRowSet jrs = null;
         try {
@@ -143,4 +208,136 @@
         }
         return -1;
     }
+    
+    
+    
+    
+
+    protected boolean dataEqualsIgnoreOrder(RowSet rowSet1, RowSet rowSet2)
+            throws SQLException {
+        // First decides if the column num are equal.
+        int columnNum = rowSet1.getMetaData().getColumnCount();
+        if (rowSet2.getMetaData().getColumnCount() != columnNum) {
+            return false;
+        }
+
+        // Then decides if the row num are equal.
+        rowSet1.beforeFirst();
+        rowSet2.beforeFirst();
+
+        while (rowSet1.next()) {
+            rowSet2.next();
+        }
+        if (!rowSet2.isLast()) {
+            return false;
+        }
+
+        // For each row in rowSet1, try to find an equal row in rowSet2.
+        // If not found, return false.
+        rowSet1.beforeFirst();
+
+        while (rowSet1.next()) {
+            boolean isRowFound = false;
+
+            rowSet2.beforeFirst();
+            while (rowSet2.next()) {
+                int i = 1;
+                for (i = 1; i <= columnNum; i++) {
+                    if (rowSet1.getObject(i) == null) {
+                        if (rowSet2.getObject(i) != null) {
+                            break;
+                        }
+                    } else if (!rowSet1.getObject(i).equals(
+                            rowSet2.getObject(i))) {
+                        break;
+                    }
+                }
+
+                if (i == columnNum + 1) {
+                    // A equal row has found
+                    isRowFound = true;
+                    break;
+                }
+            }
+
+            if (!isRowFound) {
+                return false;
+            }
+        }
+
+        // Since we have proved that for each row in rowSet1, we can find an
+        // equal row in rowSet2, so the data in these to rowSet2 are equal,
+        // ignoring order.
+        return true;
+    }
+    
+    
+
+    protected boolean dataEqualsIgnoreOrderAndNullInR2(RowSet rowSet1, RowSet rowSet2, int nullColumn)
+            throws SQLException {
+        // First decides if the column num are equal.
+        int columnNum = rowSet1.getMetaData().getColumnCount();
+        if (rowSet2.getMetaData().getColumnCount() != columnNum) {
+            return false;
+        }
+
+        // Then decides if the row num are equal.
+        rowSet1.beforeFirst();
+        rowSet2.beforeFirst();
+
+        int notNullRowNum = 0;
+        
+        while (rowSet1.next()) {
+              notNullRowNum++;
+          
+        }
+        
+        while (rowSet2.next()) {
+            if (! "null".equals(rowSet2.getObject(nullColumn))) {
+                notNullRowNum--;
+            }
+        }
+        if (notNullRowNum != 0) {
+            return false;
+        }
+
+        // For each row in rowSet1, try to find an equal row in rowSet2.
+        // If not found, return false.
+        rowSet1.beforeFirst();
+
+        while (rowSet1.next()) {
+            boolean isRowFound = false;
+
+            rowSet2.beforeFirst();
+            while (rowSet2.next()) {
+                int i = 1;
+                for (i = 1; i <= columnNum; i++) {
+                    if (rowSet1.getObject(i) == null) {
+                        if (rowSet2.getObject(i) != null) {
+                            break;
+                        }
+                    } else if (!rowSet1.getObject(i).equals(
+                            rowSet2.getObject(i))) {
+                        break;
+                    }
+                }
+
+                if (i == columnNum + 1) {
+                    // A equal row has found
+                    isRowFound = true;
+                    break;
+                }
+            }
+
+            if (!isRowFound) {
+                return false;
+            }
+        }
+
+        // Since we have proved that for each row in rowSet1, we can find an
+        // equal row in rowSet2, so the data in these to rowSet2 are equal,
+        // ignoring order.
+        return true;
+    }
+
 }



Mime
View raw message