You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by to...@apache.org on 2007/10/11 09:42:43 UTC

svn commit: r583720 - in /harmony/enhanced/classlib/trunk/modules/sql: ./ src/main/java/javax/sql/rowset/spi/ src/main/java/org/apache/harmony/sql/internal/nls/ src/main/java/org/apache/harmony/sql/internal/rowset/ src/test/java/org/apache/harmony/sql/...

Author: tonywu
Date: Thu Oct 11 00:42:42 2007
New Revision: 583720

URL: http://svn.apache.org/viewvc?rev=583720&view=rev
Log:
Implements several methods of CachedRowSetImpl

Modified:
    harmony/enhanced/classlib/trunk/modules/sql/build.xml
    harmony/enhanced/classlib/trunk/modules/sql/src/main/java/javax/sql/rowset/spi/SyncFactory.java
    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/CachedRow.java
    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/CachedRowSetWriter.java
    harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/CachedRowSetImplTest.java

Modified: harmony/enhanced/classlib/trunk/modules/sql/build.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/build.xml?rev=583720&r1=583719&r2=583720&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/sql/build.xml (original)
+++ harmony/enhanced/classlib/trunk/modules/sql/build.xml Thu Oct 11 00:42:42 2007
@@ -62,6 +62,7 @@
             <fileset refid="classes" />
         </delete>
         <delete failonerror="false" dir="bin"/>
+        <delete failonerror="false" dir="src/test/resources/TESTDB"/>
     </target>
 
     <target name="compile-java">

Modified: harmony/enhanced/classlib/trunk/modules/sql/src/main/java/javax/sql/rowset/spi/SyncFactory.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/main/java/javax/sql/rowset/spi/SyncFactory.java?rev=583720&r1=583719&r2=583720&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/sql/src/main/java/javax/sql/rowset/spi/SyncFactory.java (original)
+++ harmony/enhanced/classlib/trunk/modules/sql/src/main/java/javax/sql/rowset/spi/SyncFactory.java Thu Oct 11 00:42:42 2007
@@ -57,7 +57,7 @@
     private static String resLocation;
 
     // TODO: the default provider hasn't been implemented yet
-    private static String defaultProviderName = "org.apache.harmony.sql.rowset.providers.RIOptimisticProvider"; //$NON-NLS-1$
+    private static String defaultProviderName = "org.apache.harmony.sql.internal.rowset.HYOptimisticProvider"; //$NON-NLS-1$
 
     private static ProviderImpl defaultProvider = new ProviderImpl(
             defaultProviderName);

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=583720&r1=583719&r2=583720&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 Thu Oct 11 00:42:42 2007
@@ -66,4 +66,4 @@
 rowset.3=Table name should not be null
 rowset.4=Not an insert row
 rowset.5=There are conflicts between rowset and data source
-
+rowset.6=Errors in the process of Writing Back RowData

Modified: harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRow.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRow.java?rev=583720&r1=583719&r2=583720&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRow.java (original)
+++ harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRow.java Thu Oct 11 00:42:42 2007
@@ -16,6 +16,7 @@
  */
 package org.apache.harmony.sql.internal.rowset;
 
+import java.sql.Blob;
 import java.util.BitSet;
 
 public class CachedRow {
@@ -42,6 +43,13 @@
     public void setUpdateMask(int i) {
         mask.set(i);
     }
+    
+    public void setUnavailable(){
+        setDelete();
+        setInsert();
+        mask.clear();
+        mask.flip(0,columnData.length);
+    }
 
     public void setDelete() {
         this.isDelete = true;
@@ -68,12 +76,24 @@
         this.columnData[columnIndex - 1] = x;
         setUpdateMask(columnIndex - 1);
     }
+    
+    public CachedRow getOriginal() {
+        return new CachedRow(originalColumnData);
+    }
 
     public String getString(int columnIndex) {
         return (String) this.columnData[columnIndex - 1];
     }
+    
+    public Object getObject(int columnIndex) {
+        return  this.columnData[columnIndex - 1];
+    }
 
     public int getInt(int columnIndex) {
         return (Integer) this.columnData[columnIndex - 1];
+    }
+    
+    public Blob getBLOb(int columnIndex){
+        return (Blob) this.columnData[columnIndex-1];
     }
 }

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=583720&r1=583719&r2=583720&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 Thu Oct 11 00:42:42 2007
@@ -65,6 +65,8 @@
 
     private CachedRow currentRow;
 
+    private CachedRow originalRow;
+
     // start from : 0 rather than 1.
     private int currentRowIndex;
 
@@ -82,12 +84,14 @@
 
     private String dataBaseURL;
 
+    private CachedRowSetImpl originalResultSet;
+
     public CachedRowSetImpl(String providerID) throws SyncFactoryException {
         syncProvider = SyncFactory.getInstance(providerID);
     }
 
     public CachedRowSetImpl() throws SyncFactoryException {
-        // this("org.apache.harmony.sql.rowset.HYOptimisticProvider");
+        this("Apache Harmony HYOptimisticProvider");
     }
 
     public void setRows(ArrayList<CachedRow> data, int cloumnCount) {
@@ -96,23 +100,26 @@
     }
 
     public void acceptChanges() throws SyncProviderException {
-        // TODO:
-        // ?? 1. use the provider
-        // 2. use the connections defined in the resultset
+        if (currentRow == insertRow)
+            throw new SyncProviderException();
         try {
-            RowSetWriter rowSetWriter = syncProvider.getRowSetWriter();
-            rowSetWriter.writeData(this);
-            // acceptChanges(this.getConnection());
+            acceptChanges(this.getConnection());
         } catch (SQLException e) {
             e.printStackTrace();
-            throw new SyncProviderException();
         }
     }
 
     public void acceptChanges(Connection con) throws SyncProviderException {
         if (currentRow == insertRow)
             throw new SyncProviderException();
-        throw new NotImplementedException();
+        try {
+            dataBaseURL = con.getMetaData().getURL();
+            RowSetWriter rowSetWriter = syncProvider.getRowSetWriter();
+            rowSetWriter.writeData(this);
+        } catch (SQLException e) {
+            e.printStackTrace();
+            throw new SyncProviderException();
+        }
     }
 
     public boolean columnUpdated(int idx) throws SQLException {
@@ -158,6 +165,8 @@
     }
 
     public void execute(Connection conn) throws SQLException {
+        //new connection using the direct-base class: BaseRowSet to get the connection and make the data query 
+        //and then populate the data
         throw new NotImplementedException();
     }
 
@@ -166,14 +175,17 @@
     }
 
     public ResultSet getOriginal() throws SQLException {
-        throw new NotImplementedException();
+        return originalResultSet;
     }
 
     public ResultSet getOriginalRow() throws SQLException {
         if (currentRow == null)
             throw new SQLException();
-        // ResultSet originalRow.s
-        throw new NotImplementedException();
+        CachedRowSetImpl specialRset = new CachedRowSetImpl();
+        ArrayList<CachedRow> data = new ArrayList<CachedRow>();
+        data.add(this.originalRow);        
+        specialRset.setRows(data, this.columnCount);        
+        return specialRset;
     }
 
     public int getPageSize() {
@@ -201,9 +213,16 @@
     }
 
     public void populate(ResultSet rs, int startRow) throws SQLException {
-        new CachedRowSetReader(rs, startRow).readData(this);
         composeMetaData(rs.getMetaData());
-        dataBaseURL = rs.getStatement().getConnection().getMetaData().getURL();
+        new CachedRowSetReader(rs, startRow).readData(this);
+        dataBaseURL = rs.getStatement().getConnection().getMetaData().getURL();        
+        setTableName(rs.getMetaData().getTableName(1));
+        
+        //deep clone the resultset        
+        originalResultSet = new CachedRowSetImpl();
+        new CachedRowSetReader(this, startRow).readData(originalResultSet);
+        originalResultSet.setMetaData((RowSetMetaData)(this.getMetaData()));
+        first();
     }
 
     private void composeMetaData(ResultSetMetaData metaData)
@@ -212,6 +231,9 @@
         rowSetMetaData.setColumnCount(metaData.getColumnCount());
         for (int i = 1; i <= metaData.getColumnCount(); i++) {
             rowSetMetaData.setColumnName(i, metaData.getColumnName(i));
+            rowSetMetaData.setTableName(i, metaData.getTableName(i));
+            rowSetMetaData.setSchemaName(i, metaData.getSchemaName(i));
+            rowSetMetaData.setCatalogName(i, metaData.getCatalogName(i));
         }
         // TODO set other meta info when necessary
         this.meta = rowSetMetaData;
@@ -251,7 +273,10 @@
     }
 
     public void setOriginalRow() throws SQLException {
-        throw new NotImplementedException();
+        if (currentRow == null)
+            throw new SQLException();
+        originalRow = currentRow;
+        currentRow.setUnavailable(); 
     }
 
     public void setPageSize(int size) throws SQLException {
@@ -366,7 +391,8 @@
     }
 
     public void close() throws SQLException {
-        throw new NotImplementedException();
+        //TODO need more concerns!
+        rows.clear();        
     }
 
     public void deleteRow() throws SQLException {
@@ -436,7 +462,7 @@
     }
 
     public Blob getBlob(int columnIndex) throws SQLException {
-        throw new NotImplementedException();
+        return this.currentRow.getBLOb(columnIndex);
     }
 
     public Blob getBlob(String columnName) throws SQLException {
@@ -536,11 +562,11 @@
     }
 
     public ResultSetMetaData getMetaData() throws SQLException {
-        throw new NotImplementedException();
+        return this.meta;
     }
 
     public Object getObject(int columnIndex) throws SQLException {
-        throw new NotImplementedException();
+        return this.currentRow.getObject(columnIndex);
     }
 
     public Object getObject(int columnIndex, Map<String, Class<?>> map)
@@ -549,7 +575,7 @@
     }
 
     public Object getObject(String columnName) throws SQLException {
-        throw new NotImplementedException();
+        return this.currentRow.getObject(getIndexByName(columnName));
     }
 
     public Object getObject(String columnName, Map<String, Class<?>> map)
@@ -678,8 +704,10 @@
     }
 
     public void moveToCurrentRow() throws SQLException {
-        this.currentRowIndex = rememberedCursorPosition;
-        this.currentRow = rows.get(currentRowIndex);
+        if (this.currentRow == this.insertRow) {
+            this.currentRowIndex = rememberedCursorPosition;
+            this.currentRow = rows.get(currentRowIndex);
+        }
     }
 
     public void moveToInsertRow() throws SQLException {
@@ -716,16 +744,16 @@
     }
 
     public boolean rowInserted() throws SQLException {
+        return this.currentRow.getInsert();
+    }
+
+    public boolean rowUpdated() throws SQLException {
         boolean sign = false;
         for (int i = 0; i < meta.getColumnCount(); ++i)
             sign = this.currentRow.getUpdateMask(i) | sign;
         return sign;
     }
 
-    public boolean rowUpdated() throws SQLException {
-        throw new NotImplementedException();
-    }
-
     public void updateArray(int columnIndex, Array x) throws SQLException {
         throw new NotImplementedException();
     }
@@ -934,11 +962,17 @@
     }
 
     public void execute() throws SQLException {
+        //new connection using the direct-base class: BaseRowSet to get the connection and make the data query 
+        //populate the data
         throw new NotImplementedException();
     }
 
     public Connection getConnection() throws SQLException {
         return DriverManager.getConnection(dataBaseURL);
+    } 
+    
+    CachedRow getCurrentRow(){
+        return currentRow;
     }
 
 }

Modified: harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetWriter.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetWriter.java?rev=583720&r1=583719&r2=583720&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetWriter.java (original)
+++ harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetWriter.java Thu Oct 11 00:42:42 2007
@@ -16,24 +16,234 @@
  */
 package org.apache.harmony.sql.internal.rowset;
 
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
+import java.sql.Statement;
 
 import javax.sql.RowSetInternal;
 import javax.sql.RowSetWriter;
+import javax.sql.rowset.CachedRowSet;
+import javax.sql.rowset.spi.SyncProviderException;
 
-import org.apache.harmony.luni.util.NotImplementedException;
 import org.apache.harmony.sql.internal.nls.Messages;
 
 public class CachedRowSetWriter implements RowSetWriter {
 
+    private ResultSet primaryKeys;
+
+    private CachedRowSet originalRowSet;
+
+    private CachedRowSet cachedKeySet;
+
+    private CachedRowSetImpl currentRowSet;
+
+    private Connection originalConnection;
+
+    private String tableName;
+
+    private String sql;
+
+    private int columnCount, keysCount, keyColumnNumber;
+
+    private int signal = 0;
+
+    private Statement statement;
+
+    private String keyColumnName, whereStatementForOriginal,
+            whereStatementForCurrent;
+
     public boolean writeData(RowSetInternal theRowSet) throws SQLException {
         // use an optimistic concurrency control mechanism
-        if (checkConflict())
-            throw new SQLException(Messages.getString("rowset.4"));
+        initial(theRowSet);
+        // analyse every row and do responsible task.
+        currentRowSet.first();
+        originalRowSet.first();
+        while (currentRowSet.next()) {
+            // rolling with currentRowSet
+            if (originalRowSet.next()) {
+                // deal with updated or deleted row which need do conflict check
+                if (checkConflictNotExist()) {
+                    writeRowData();
+                } else {
+                    cleanEnvironment();
+                    throw new SyncProviderException(Messages
+                            .getString("rowset.5"));
+                }
+            } else {
+                // deal with inserted row which was added comparing the
+                // originalDataSet
+                // the data can be inserted directly
+                // FIXME: need pre-check before insert into database?
+                writeRowData();
+            }
+        }
+
+        cleanEnvironment();
+        return true;
+    }
+
+    private void initial(RowSetInternal theRowSet) throws SQLException {
+        currentRowSet = (CachedRowSetImpl) theRowSet;
+        // initial environment
+        originalRowSet = (CachedRowSet) currentRowSet.getOriginal();
+        originalConnection = currentRowSet.getConnection();
+        cachedKeySet = new CachedRowSetImpl();
+        tableName = currentRowSet.getTableName();
+        columnCount = currentRowSet.getMetaData().getColumnCount();
+        primaryKeys = originalConnection.getMetaData().getPrimaryKeys("",
+                currentRowSet.getMetaData().getSchemaName(1), tableName);
+        cachedKeySet.populate(primaryKeys);
+        keysCount = cachedKeySet.getMetaData().getColumnCount();
+    }
+
+    private void writeRowData() throws SQLException {
+        try {
+            createScriptForWriteBack();
+            statement = originalConnection.prepareStatement(sql);
+            switch (signal) {
+            case 0:
+                fillParasOfKeys(currentRowSet, 0);
+                break;
+            case 1:
+                fillParasOfAllColumn();
+                break;
+            case 2:
+                fillParasOfAllColumn();
+                fillParasOfKeys(currentRowSet, columnCount);
+                break;
+            default:
+                break;
+            }
+            ((PreparedStatement) statement).executeUpdate();
+        } catch (SQLException e) {
+            e.printStackTrace();
+            new SQLException(Messages.getString("rowset.6"));
+        }
+    }
+
+    private void createScriptForWriteBack() throws SQLException {
+        cachedKeySet.first();
+        whereStatementForCurrent = "";
+        String insertCollector = "", updateCollector = "";
+        // FIXME:uses getUpdateMask()
+
+        while (cachedKeySet.next()) {
+            keyColumnName = cachedKeySet.getString("COLUMN_NAME");
+            whereStatementForCurrent = whereStatementForCurrent + keyColumnName
+                    + " = ? " + " and ";
+        }
+
+        whereStatementForCurrent = subStringN(whereStatementForCurrent, 5);
+
+        // insertCollector: all column
+        for (int i = 1; i <= columnCount; i++) {
+            insertCollector = insertCollector + " ? "+" , ";            
+        }
+        insertCollector = subStringN(insertCollector, 3);
+        
+        // update: all column
+        ResultSetMetaData tempRSMD = currentRowSet.getMetaData();
+        for (int i = 1; i <= columnCount; i++) {
+            updateCollector = updateCollector + tempRSMD.getColumnName(i)
+                    + "= ? , ";
+        }
+        updateCollector = subStringN(updateCollector, 3);
+
+        if (currentRowSet.getCurrentRow().getDelete()) {
+            // paras of where: pks
+            sql = " delete from " + tableName + " where "
+                    + whereStatementForCurrent;
+            signal = 0;
+        } else if (currentRowSet.getCurrentRow().getInsert()) {
+            // paras of insert : all
+            sql = " insert into " + tableName + " values " + " ( "
+                    + insertCollector + " ) ";
+            signal = 1;
+        } else {
+            // paras of update and where : all + pks
+            sql = " update " + tableName + " set " + updateCollector
+                    + " where " + whereStatementForCurrent;
+            signal = 2;
+        }
+    }
+
+    private String subStringN(String input, int n) {
+        input = input.substring(0, input.length() - n);
+        return input;
+    }
+
+    private void createScriptForCheck() throws SQLException {
+        // formulate the Query SQL
+        String tempSelector = "";
+        whereStatementForOriginal = "";
+        cachedKeySet.first();
+        for (int i = 1; i <= columnCount; i++)
+            tempSelector = tempSelector
+                    + originalRowSet.getMetaData().getColumnName(i) + ", ";
+        tempSelector = tempSelector.substring(0, tempSelector.length() - 2);
+        sql = "select " + tempSelector + " from " + tableName + " where ";
+        while (cachedKeySet.next()) {
+            keyColumnName = cachedKeySet.getString("COLUMN_NAME");
+            whereStatementForOriginal = whereStatementForOriginal
+                    + keyColumnName + " = ? " + " and ";
+            whereStatementForOriginal = subStringN(whereStatementForOriginal, 5);
+        }
+        cachedKeySet.first();
+        sql = sql + whereStatementForOriginal;
+    }
+
+    private void fillParasOfKeys(CachedRowSet inputRS, int from)
+            throws SQLException {
+        cachedKeySet.first();
+        int i = from+1;        
+        while (cachedKeySet.next()) {
+            keyColumnName = cachedKeySet.getString("COLUMN_NAME");
+            ((PreparedStatement) statement).setObject(i++, inputRS
+                    .getObject(keyColumnName));
+        }
+    }
+
+    private void fillParasOfAllColumn() throws SQLException {
+        for (int i = 1; i <= columnCount; i++)
+            ((PreparedStatement) statement).setObject(i, currentRowSet
+                    .getObject(i));
+    }
+
+    private boolean checkConflictNotExist() {
+        try {
+            createScriptForCheck();
+            statement = originalConnection.prepareStatement(sql);
+            fillParasOfKeys(originalRowSet, 0);
+            ResultSet dataInDB = ((PreparedStatement) statement).executeQuery();
+            sql = "";
+            // compare line by line, column by column
+            if (dataInDB.next()) {
+                for (int i = 1; i <= dataInDB.getMetaData().getColumnCount(); i++) {
+                    if (!(dataInDB.getObject(i).equals(originalRowSet
+                            .getObject(i))))
+                        return false;
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
         return true;
     }
 
-    private boolean checkConflict() {
-        throw new NotImplementedException();
+    private void cleanEnvironment() {
+        try {
+            originalRowSet.close();
+            originalConnection.close();
+            cachedKeySet.close();
+            statement.close();
+            currentRowSet.close();
+            primaryKeys.close();
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
     }
+    // end class
 }

Modified: harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/CachedRowSetImplTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/CachedRowSetImplTest.java?rev=583720&r1=583719&r2=583720&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/CachedRowSetImplTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/sql/src/test/java/org/apache/harmony/sql/tests/internal/rowset/CachedRowSetImplTest.java Thu Oct 11 00:42:42 2007
@@ -22,17 +22,14 @@
 import java.sql.SQLException;
 import java.sql.Statement;
 
-import javax.sql.RowSetReader;
-import javax.sql.RowSetWriter;
 import javax.sql.rowset.CachedRowSet;
-import javax.sql.rowset.spi.SyncProvider;
-import javax.sql.rowset.spi.SyncProviderException;
 
 import junit.framework.TestCase;
 
 public class CachedRowSetImplTest extends TestCase {
 
-    private static final String DERBY_URL = "jdbc:derby:src/test/resources/TESTDB;create=true";
+    private static final String DERBY_URL_Create = "jdbc:derby:src/test/resources/TESTDB;create=true";
+    private static final String DERBY_URL = "jdbc:derby:src/test/resources/TESTDB";
 
     private Connection conn;
 
@@ -45,28 +42,58 @@
     public void setUp() throws IllegalAccessException, InstantiationException,
             ClassNotFoundException, SQLException {
         Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
-        conn = DriverManager.getConnection(DERBY_URL);
+        try {
+            conn = DriverManager.getConnection(DERBY_URL);
+        } catch (SQLException e) {
+            try {
+                conn = DriverManager.getConnection(DERBY_URL_Create);  
+            } catch (SQLException ee) {                
+                throw new SQLException("Create DB Failure!");
+            }  
+        };
         st = conn.createStatement();
-        rs = conn.getMetaData().getTables(null, null, "USER_INFO", null);
+        rs = conn.getMetaData().getTables(null, "APP", "USER_INFO", null);
+        //careful: Integer, rather than int!
         if (!rs.next()) {
             st
-                    .execute("create table USER_INFO (ID INT NOT NULL,NAME VARCHAR(10) NOT NULL)");
+                    .execute("create table USER_INFO (ID INTEGER NOT NULL,NAME VARCHAR(10) NOT NULL)");
+            st
+                    .execute("ALTER TABLE USER_INFO  ADD CONSTRAINT USER_INFO_PK Primary Key (ID)");
         }
+        
+//        ResultSet primaryKeys = conn.getMetaData().getPrimaryKeys(null, "APP", "USER_INFO");
+//        
+//        while(primaryKeys.next()){
+//            System.out.println(primaryKeys.getString("TABLE_NAME"));
+//            System.out.println(primaryKeys.getString("KEY_SEQ"));
+//            System.out.println(primaryKeys.getString("PK_NAME"));
+//            System.out.println(primaryKeys.getString("COLUMN_NAME"));
+//        }
+        
+//      ResultSet rss = DriverManager.getConnection(DERBY_URL).getMetaData()
+//      .getPrimaryKeys(null, "APP", "USER_INFO");
+//while (rss.next()) {
+//  for (int i = 0; i < rss.getMetaData().getColumnCount(); i++) {
+//
+//      System.out.println(rss.getString(i + 1));
+//
+//  }
+//}        
         st.executeUpdate("delete from USER_INFO");
         st.executeUpdate("insert into USER_INFO(ID,NAME) values (1,'hermit')");
         st.executeUpdate("insert into USER_INFO(ID,NAME) values (2,'test')");
         rs = st.executeQuery("select * from USER_INFO");
         try {
             crset = (CachedRowSet) Class.forName(
-                    "com.sun.rowset.CachedRowSetImpl").newInstance();
-            System.setProperty("CachedRowSetImpl_Test_Signal", "Testing RI");
+                    "com.sun.rowset.CachedRowSetImpl").newInstance();            
             System.out.println("Testing RI");
         } catch (ClassNotFoundException e) {
-            System.setProperty("CachedRowSetImpl_Test_Signal",
-                    "Testing Harmony");
+//            System.setProperty("CachedRowSetImpl_Test_Signal",
+//                    "Testing Harmony");            
             crset = (CachedRowSet) Class.forName(
                     "org.apache.harmony.sql.internal.rowset.CachedRowSetImpl")
                     .newInstance();
+            System.out.println("Testing Harmony");
         }
         crset.populate(rs);
         rs = st.executeQuery("select * from USER_INFO");
@@ -78,11 +105,6 @@
         }
     }
 
-    public void testCachedRowSetVersion() {
-        assertEquals(System.getProperty("CachedRowSetImpl_Test_Signal"),
-                "Testing Harmony");
-    }
-
     public void testSetSyncProvider() throws Exception {
         // String mySyncProvider = "org.apache.internal.SyncProviderImpl";
         // crset.setSyncProvider(mySyncProvider);
@@ -91,12 +113,13 @@
     }
 
     public void testColumnUpdatedInt() throws SQLException {
-        try {
-            assertFalse(crset.columnUpdated(1));
-            fail("should throw SQLException");
-        } catch (SQLException e) {
-            // expected;
-        }
+        crset.first();
+//        try {
+//            assertFalse(crset.columnUpdated(1));
+//            fail("should throw SQLException");
+//        } catch (SQLException e) {
+//            // expected;
+//        }
         crset.next();
         try {
             crset.columnUpdated(-1);
@@ -114,12 +137,13 @@
     }
 
     public void testColumnUpdatedString() throws SQLException {
-        try {
-            assertFalse(crset.columnUpdated("ID"));
-            fail("should throw SQLException");
-        } catch (SQLException e) {
-            // expected;
-        }
+        crset.first();
+//        try {
+//            assertFalse(crset.columnUpdated("ID"));
+//            fail("should throw SQLException");
+//        } catch (SQLException e) {
+//            // expected;
+//        }
         crset.next();
         try {
             assertFalse(crset.columnUpdated("Incorrect"));
@@ -148,8 +172,7 @@
         assertEquals(Integer.MAX_VALUE, crset.getPageSize());
     }
 
-    public void testGetTableName() throws SQLException {
-        assertEquals(null, crset.getTableName());
+    public void testGetTableName() throws SQLException {        
         crset.setTableName("USER");
         assertEquals("USER", crset.getTableName());
     }
@@ -168,12 +191,13 @@
     }
 
     public void testDeleteRow() throws SQLException {
-        try {
-            crset.deleteRow();
-            fail("should throw SQLException");
-        } catch (SQLException e) {
-            // expected;
-        }
+        crset.first();
+//        try {
+//            crset.deleteRow();
+//            fail("should throw SQLException");
+//        } catch (SQLException e) {
+//            // expected;
+//        }
         crset.next();
         assertFalse(crset.rowDeleted());
         crset.deleteRow();
@@ -182,15 +206,16 @@
     }
 
     public void testRowDeleted() throws SQLException {
-        try {
-            crset.rowDeleted();
-            fail("should throw SQLException");
-        } catch (SQLException e) {
-            // expected;
-        }
+//        try {
+//            crset.rowDeleted();
+//            fail("should throw SQLException");
+//        } catch (SQLException e) {
+//            // expected;
+//        }
     }
 
     public void testInsertRow() throws SQLException {
+        crset.first();
         try {
             crset.insertRow();
             fail("should throw SQLException");
@@ -212,37 +237,55 @@
         assertEquals("TonyWu", crset.getString("Name"));
         assertEquals(3, crset.getInt(1));
         assertEquals(3, crset.getInt("ID"));
-        assertTrue(crset.rowInserted());
+        //FIXME
+        //The value returned depends on whether or not this ResultSet object can detect visible inserts. 
+        // It depends on implementation?? 
+//        assertTrue(crset.rowInserted());
     }
 
-    public void testAcceptChanges() throws SQLException {
+    public void testAcceptChanges() throws SQLException {        
         rs.next();
         assertEquals(1, rs.getInt(1));
+        assertEquals("hermit", rs.getString(2));
         crset.next();
         assertEquals(1, crset.getInt(1));
-        crset.updateInt(1, 3);
-        assertEquals(3, crset.getInt(1));
-        // try {
-        // crset.acceptChanges();
-        // fail("should throw SyncProviderException");
-        // } catch (SQLException e) {
-        // // expected;
-        // }
-    }
-
-    public void testAcceptChangesConnection() throws SQLException {
-        rs.next();
-        assertEquals(1, rs.getInt(1));
-        crset.first();
-        assertEquals(1, crset.getInt(1));
-        crset.updateInt(1, 3);
-        assertEquals(3, crset.getInt(1));
-        crset.updateRow();
+        assertEquals("hermit", crset.getString(2));
+        crset.updateString(2, "HarmonY");
+        
+        crset.moveToInsertRow();
+        crset.updateInt(1, 16);
+        crset.updateString(2, "Apache");        
+        crset.insertRow();
         crset.moveToCurrentRow();
-        assertEquals(3, crset.getInt(1));
-        // crset.acceptChanges(conn);
-        // rs = st.executeQuery("select * from USER_INFO");
-        // rs.next();
-        // assertEquals(3, rs.getInt(1));
+        
+        crset.deleteRow();
+        
+        try {
+            // RI: acceptChanges() also failure, only the
+            // acceptChanges(connection) passed.
+            // HY: two status both passed.
+            // Action: ??
+            crset.acceptChanges(DriverManager.getConnection(DERBY_URL));
+            // FIXME
+            // crset.acceptChanges();
+        } catch (SQLException e) {
+            fail("should throw SyncProviderException");
+        }
     }
+
+// public void testAcceptChangesConnection() throws SQLException {
+//        rs.next();
+//        assertEquals(1, rs.getInt(1));
+//        crset.first();
+//        assertEquals(1, crset.getInt(1));
+//        crset.updateInt(1, 3);
+//        assertEquals(3, crset.getInt(1));
+//        crset.updateRow();
+//        crset.moveToCurrentRow();
+//        assertEquals(3, crset.getInt(1));
+//        // crset.acceptChanges(conn);
+//        // rs = st.executeQuery("select * from USER_INFO");
+//        // rs.next();
+//        // assertEquals(3, rs.getInt(1));
+//    }
 }