Return-Path: Delivered-To: apmail-harmony-commits-archive@www.apache.org Received: (qmail 66510 invoked from network); 6 Nov 2007 06:45:09 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 6 Nov 2007 06:45:09 -0000 Received: (qmail 75635 invoked by uid 500); 6 Nov 2007 06:44:57 -0000 Delivered-To: apmail-harmony-commits-archive@harmony.apache.org Received: (qmail 75614 invoked by uid 500); 6 Nov 2007 06:44:57 -0000 Mailing-List: contact commits-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list commits@harmony.apache.org Received: (qmail 75605 invoked by uid 99); 6 Nov 2007 06:44:57 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 05 Nov 2007 22:44:57 -0800 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 06 Nov 2007 06:45:08 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 021021A9832; Mon, 5 Nov 2007 22:44:43 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r592309 - in /harmony/enhanced/classlib/trunk/modules/sql/src: main/java/javax/sql/rowset/ 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: Tue, 06 Nov 2007 06:44:38 -0000 To: commits@harmony.apache.org From: tonywu@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20071106064447.021021A9832@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: tonywu Date: Mon Nov 5 22:44:32 2007 New Revision: 592309 URL: http://svn.apache.org/viewvc?rev=592309&view=rev Log: impl several methods of CachedRowsetImpl Modified: harmony/enhanced/classlib/trunk/modules/sql/src/main/java/javax/sql/rowset/BaseRowSet.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/CachedRowSetReader.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/main/java/org/apache/harmony/sql/internal/rowset/HYOptimisticProvider.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/src/main/java/javax/sql/rowset/BaseRowSet.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/main/java/javax/sql/rowset/BaseRowSet.java?rev=592309&r1=592308&r2=592309&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/sql/src/main/java/javax/sql/rowset/BaseRowSet.java (original) +++ harmony/enhanced/classlib/trunk/modules/sql/src/main/java/javax/sql/rowset/BaseRowSet.java Mon Nov 5 22:44:32 2007 @@ -79,7 +79,8 @@ private int concurrency = ResultSet.CONCUR_UPDATABLE; - private boolean readOnly; + //compatiable with RI, default: true + private boolean readOnly = true; private boolean escapeProcessing; @@ -723,5 +724,11 @@ result[i] = param; } return result; + } + + public BaseRowSet clone() throws CloneNotSupportedException{ + BaseRowSet result = (BaseRowSet) super.clone(); + return result; + } } 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=592309&r1=592308&r2=592309&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 Mon Nov 5 22:44:32 2007 @@ -67,3 +67,6 @@ 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 +rowset.7=Not a valid cursor +rowset.8=The Result Set Type is TYPE_FORWARD_ONLY +rowset.9=PageSize can not larger than MaxRows 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=592309&r1=592308&r2=592309&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 Mon Nov 5 22:44:32 2007 @@ -16,10 +16,12 @@ */ package org.apache.harmony.sql.internal.rowset; + import java.sql.Blob; +import java.sql.SQLException; import java.util.BitSet; -public class CachedRow { +public class CachedRow implements Cloneable{ private Object[] columnData; private Object[] originalColumnData; @@ -30,6 +32,8 @@ private boolean insert; + private boolean nonUpdateable = false; + public CachedRow(Object[] columnData) { this.columnData = columnData; this.originalColumnData = columnData; @@ -51,9 +55,25 @@ mask.flip(0,columnData.length); } + public void setNonUpdateable() { + // setDelete(); + // setInsert(); + // mask.clear(); + // mask.flip(0,columnData.length); + nonUpdateable = true; + } + + public boolean getNonUpdateable() { + return nonUpdateable; + } + public void setDelete() { this.isDelete = true; } + + public void unDoDelete() { + this.isDelete = false; + } public boolean getDelete() { return isDelete; @@ -67,7 +87,9 @@ return this.insert; } - public void updateString(int columnIndex, String x) { + public void updateString(int columnIndex, String x) throws SQLException { + if (nonUpdateable) + throw new SQLException("Not Updateable of the CurrentRow"); this.columnData[columnIndex - 1] = x; setUpdateMask(columnIndex - 1); } @@ -86,14 +108,43 @@ } public Object getObject(int columnIndex) { - return this.columnData[columnIndex - 1]; + 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]; + + public Blob getBLOb(int columnIndex) { + return (Blob) this.columnData[columnIndex - 1]; + } + + public boolean getBoolean(int columnIndex) { + return (Boolean) this.columnData[columnIndex - 1]; + } + + public byte getByte(int columnIndex) { + return (Byte) this.columnData[columnIndex - 1]; + } + + public byte[] getBytes(int columnIndex) { + return (byte[]) this.columnData[columnIndex - 1]; + } + + // deep clone + public CachedRow createClone() throws CloneNotSupportedException { + CachedRow cr = (CachedRow) super.clone(); + + Object[] cd = new Object[columnData.length]; + for (int i = 0; i < columnData.length; i++) { + cd[i] = columnData[i]; + } + cr.columnData = cd; + cr.insert = insert; + cr.isDelete = isDelete; + cr.mask = (BitSet) mask.clone(); + cr.nonUpdateable = nonUpdateable; + // cr.originalColumnData + return cr; } } 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=592309&r1=592308&r2=592309&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 Mon Nov 5 22:44:32 2007 @@ -25,6 +25,7 @@ import java.sql.Connection; import java.sql.Date; import java.sql.DriverManager; +import java.sql.PreparedStatement; import java.sql.Ref; import java.sql.ResultSet; import java.sql.ResultSetMetaData; @@ -59,6 +60,8 @@ public class CachedRowSetImpl extends BaseRowSet implements CachedRowSet, RowSetInternal { + private static final long serialVersionUID = 1L; + private ArrayList rows; private RowSetMetaData meta; @@ -67,25 +70,32 @@ private CachedRow originalRow; - // start from : 0 rather than 1. + // start from : 1. private int currentRowIndex; + // the number of the rows in one "page" private int pageSize; + private int pageNumber = 1; + private String tableName; private int rememberedCursorPosition; private CachedRow insertRow; + private int[] keyCols; + private int columnCount; private SyncProvider syncProvider; - private String dataBaseURL; - private CachedRowSetImpl originalResultSet; + private Object currentColumn; + + private SQLWarning sqlwarn; + public CachedRowSetImpl(String providerID) throws SyncFactoryException { syncProvider = SyncFactory.getInstance(providerID); } @@ -113,9 +123,12 @@ if (currentRow == insertRow) throw new SyncProviderException(); try { - dataBaseURL = con.getMetaData().getURL(); + setUrl(con.getMetaData().getURL()); RowSetWriter rowSetWriter = syncProvider.getRowSetWriter(); - rowSetWriter.writeData(this); + CachedRowSetImpl input = (CachedRowSetImpl) createCopy(); + rowSetWriter.writeData(input); + // setOriginalRow(); + notifyRowSetChanged(); } catch (SQLException e) { e.printStackTrace(); throw new SyncProviderException(); @@ -145,33 +158,140 @@ } public void commit() throws SQLException { - throw new NotImplementedException(); + getConnection().commit(); } public CachedRowSet createCopy() throws SQLException { - throw new NotImplementedException(); + CachedRowSetImpl output; + try { + output = (CachedRowSetImpl) super.clone(); + // restore "this"'s states + int temp = currentRowIndex; + CachedRow cr; + if (currentRow != null) + cr = currentRow.createClone(); + else + cr = null; + first(); + + // Deep Copy + ArrayList data = new ArrayList(); + + do { + data.add(currentRow.createClone()); + } while (next()); + + // TODO: should be the same granularity with RI using Debug tool + // inspect! + ((CachedRowSetImpl) output).setRows(data, columnCount); + output.setMetaData(((RowSetMetaDataImpl) getMetaData())); + output.originalResultSet = this.originalResultSet; + output.setUrl(getUrl()); + output.setTableName(getTableName()); + + // Constraints + output.setReadOnly(isReadOnly()); + output.setConcurrency(this.getConcurrency()); + output.setType(this.getType()); + + // recovery this's state for the modification of the operation + // first() and next(); + currentRow = cr; + currentRowIndex = temp; + + return output; + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + return null; + } } public CachedRowSet createCopyNoConstraints() throws SQLException { - throw new NotImplementedException(); + CachedRowSetImpl output; + try { + output = (CachedRowSetImpl) super.clone(); + // restore "this"'s states + int temp = currentRowIndex; + CachedRow cr; + if (currentRow != null) + cr = currentRow.createClone(); + else + cr = null; + first(); + + // Deep Copy + ArrayList data = new ArrayList(); + do { + data.add(currentRow.createClone()); + } while (next()); + + // TODO: should be the same granularity with RI using Debug tool + // inspect! + ((CachedRowSetImpl) output).setRows(data, columnCount); + output.setMetaData((RowSetMetaData) (this.getMetaData())); + output.originalResultSet = this.originalResultSet; + output.setUrl(getUrl()); + output.setTableName(getTableName()); + + // recovery this's state for the modification of the operation + // first() and next(); + currentRow = cr; + currentRowIndex = temp; + + return output; + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + return null; + } } public CachedRowSet createCopySchema() throws SQLException { - throw new NotImplementedException(); + // For webRowSet: represent the table structure: Columns + CachedRowSetImpl result; + try { + result = (CachedRowSetImpl) super.clone(); + result.meta = (RowSetMetaDataImpl) meta; + result.keyCols = this.keyCols == null ? null : this.keyCols.clone(); + return result; + } catch (CloneNotSupportedException e1) { + return null; + } } public RowSet createShared() throws SQLException { - throw new NotImplementedException(); + // shallow copy + CachedRowSetImpl result = new CachedRowSetImpl(); + result.rows = this.rows; + + result.currentRowIndex = this.currentRowIndex; + result.currentRow = this.currentRow; + result.meta = this.meta; + + result.setReadOnly(isReadOnly()); + result.setConcurrency(super.getConcurrency()); + result.setType(super.getType()); + + return result; } 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(); + // ensure the getConnection can works! + String localCommand = getCommand(); + if (localCommand == null || getParams() == null) + throw new SQLException(); + + PreparedStatement ps = conn.prepareStatement(localCommand); + Object[] params = getParams(); + for (int i = 0; i < params.length; i++) + ps.setObject(i + 1, params[i]); + + if (ps.execute()) { + populate(ps.getResultSet()); + } } public int[] getKeyColumns() throws SQLException { - throw new NotImplementedException(); + return keyCols.clone(); } public ResultSet getOriginal() throws SQLException { @@ -183,8 +303,8 @@ throw new SQLException(); CachedRowSetImpl specialRset = new CachedRowSetImpl(); ArrayList data = new ArrayList(); - data.add(this.originalRow); - specialRset.setRows(data, this.columnCount); + data.add(this.originalRow); + specialRset.setRows(data, this.columnCount); return specialRset; } @@ -204,25 +324,35 @@ return tableName; } + /** + * refill the cachedrowset with pagesize, and the previous rowset was + * replaced + */ public boolean nextPage() throws SQLException { - throw new NotImplementedException(); + pageNumber++; + return false; } public void populate(ResultSet data) throws SQLException { - populate(data, 0); + populate(data, -1); } public void populate(ResultSet rs, int startRow) throws SQLException { + initParams(); composeMetaData(rs.getMetaData()); + 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(); + originalResultSet.setMetaData((RowSetMetaData) (this.getMetaData())); + + // recovery the states + currentRow = null; + currentRowIndex = 0; + } private void composeMetaData(ResultSetMetaData metaData) @@ -240,7 +370,8 @@ } public boolean previousPage() throws SQLException { - throw new NotImplementedException(); + // TODO + return false; } public void release() throws SQLException { @@ -265,7 +396,7 @@ } public void setKeyColumns(int[] keys) throws SQLException { - throw new NotImplementedException(); + keyCols = keys.clone(); } public void setMetaData(RowSetMetaData md) throws SQLException { @@ -273,10 +404,12 @@ } public void setOriginalRow() throws SQLException { + if (currentRow == null) throw new SQLException(); originalRow = currentRow; - currentRow.setUnavailable(); + currentRow.setNonUpdateable(); + } public void setPageSize(int size) throws SQLException { @@ -284,13 +417,12 @@ // rowset.2=Negative page size throw new SQLException(Messages.getString("rowset.2")); } + if ((getMaxRows() != 0) && (getMaxRows() < size)) + throw new SQLException(Messages.getString("rowset.9")); this.pageSize = size; } public void setSyncProvider(String provider) throws SQLException { - // If a different concurrency control mechanism is desired, a different - // implementation of SyncProvider can be plugged in using the method - // setSyncProvider syncProvider = SyncFactory.getInstance(provider); } @@ -319,7 +451,10 @@ } public void undoDelete() throws SQLException { - throw new NotImplementedException(); + if (currentRow == null) + throw new SQLException(); + if (currentRow.getDelete()) + currentRow.unDoDelete(); } public void undoInsert() throws SQLException { @@ -371,15 +506,35 @@ } public boolean absolute(int row) throws SQLException { - throw new NotImplementedException(); + if (rows.size() == 0) + return false; + if (getType() == ResultSet.TYPE_FORWARD_ONLY) + throw new SQLException(); + if (row < 0) { + row = rows.size() + row + 1; + } else if (row == 0) { + this.currentRowIndex = row; + this.currentRow = null; + return true; + } + + this.currentRowIndex = row; + this.currentRow = (CachedRow) rows.get(currentRowIndex - 1); + return true; } public void afterLast() throws SQLException { - throw new NotImplementedException(); + if (getType() == TYPE_FORWARD_ONLY) + throw new SQLException(Messages.getString("rowset.8")); + currentRowIndex = rows.size() + 1; + currentRow = null; } public void beforeFirst() throws SQLException { - throw new NotImplementedException(); + if (getType() == TYPE_FORWARD_ONLY) + throw new SQLException(Messages.getString("rowset.8")); + currentRowIndex = 0; + currentRow = null; } public void cancelRowUpdates() throws SQLException { @@ -391,8 +546,13 @@ } public void close() throws SQLException { - //TODO need more concerns! - rows.clear(); + + // TODO need more concerns! + rows.clear(); + currentRowIndex = 0; + currentRow = null; + meta = null; + } public void deleteRow() throws SQLException { @@ -412,11 +572,7 @@ } public boolean first() throws SQLException { - if (rows.size() == 0) - return false; - this.currentRowIndex = 0; - this.currentRow = (CachedRow) rows.get(0); - return true; + return absolute(1); } public Array getArray(int columnIndex) throws SQLException { @@ -466,31 +622,31 @@ } public Blob getBlob(String columnName) throws SQLException { - throw new NotImplementedException(); + return this.currentRow.getBLOb(getIndexByName(columnName)); } public boolean getBoolean(int columnIndex) throws SQLException { - throw new NotImplementedException(); + return this.currentRow.getBoolean(columnIndex); } public boolean getBoolean(String columnName) throws SQLException { - throw new NotImplementedException(); + return this.currentRow.getBoolean(getIndexByName(columnName)); } public byte getByte(int columnIndex) throws SQLException { - throw new NotImplementedException(); + return this.currentRow.getByte(columnIndex); } public byte getByte(String columnName) throws SQLException { - throw new NotImplementedException(); + return this.currentRow.getByte(getIndexByName(columnName)); } public byte[] getBytes(int columnIndex) throws SQLException { - throw new NotImplementedException(); + return this.currentRow.getBytes(columnIndex); } public byte[] getBytes(String columnName) throws SQLException { - throw new NotImplementedException(); + return this.currentRow.getBytes(getIndexByName(columnName)); } public Reader getCharacterStream(int columnIndex) throws SQLException { @@ -546,6 +702,7 @@ } public int getInt(int columnIndex) throws SQLException { + checkCursorValid(); return this.currentRow.getInt(columnIndex); } @@ -612,6 +769,13 @@ return currentRow.getString(columnIndex); } + private boolean checkCursorValid() throws SQLException { + if ((currentRowIndex <= 0) || (currentRowIndex > rows.size())) + throw new SQLException(Messages.getString("rowset.7")); + else + return false; + } + public String getString(String columnName) throws SQLException { return currentRow.getString(getIndexByName(columnName)); } @@ -700,14 +864,16 @@ } public boolean last() throws SQLException { - throw new NotImplementedException(); + return absolute(-1); } public void moveToCurrentRow() throws SQLException { + if (this.currentRow == this.insertRow) { this.currentRowIndex = rememberedCursorPosition; - this.currentRow = rows.get(currentRowIndex); + this.currentRow = rows.get(currentRowIndex - 1); } + } public void moveToInsertRow() throws SQLException { @@ -727,7 +893,12 @@ } public boolean previous() throws SQLException { - throw new NotImplementedException(); + currentRowIndex--; + if (rows.size() < currentRowIndex) { + return false; + } + currentRow = rows.get(currentRowIndex - 1); + return true; } public void refreshRow() throws SQLException { @@ -740,14 +911,21 @@ public boolean rowDeleted() throws SQLException { checkValidRow(); + checkCursorValid(); return currentRow.getDelete(); } public boolean rowInserted() throws SQLException { + + /** + * FIXME: Determin the currentRow if have had a insertion 1. Need + * traverse the rows and find if the data hava been added + */ 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; @@ -921,6 +1099,7 @@ || (this.getConcurrency() == (ResultSet.CONCUR_READ_ONLY))) throw new SQLException(); rows.set(currentRowIndex, currentRow); + notifyRowChanged(); } public void updateShort(int columnIndex, short x) throws SQLException { @@ -958,21 +1137,26 @@ } public boolean wasNull() throws SQLException { + // return (currentColumn instanceof Types(Types.NULL)); throw new NotImplementedException(); } 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(); + execute(getConnection()); } public Connection getConnection() throws SQLException { - return DriverManager.getConnection(dataBaseURL); - } - - CachedRow getCurrentRow(){ + return DriverManager.getConnection(getUrl()); + } + + CachedRow getCurrentRow() { return currentRow; + } + + @Override + public void setCommand(String cmd) throws SQLException { + initParams(); + super.setCommand(cmd); } } Modified: harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetReader.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetReader.java?rev=592309&r1=592308&r2=592309&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetReader.java (original) +++ harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetReader.java Mon Nov 5 22:44:32 2007 @@ -23,6 +23,7 @@ import javax.sql.RowSetInternal; import javax.sql.RowSetReader; +import javax.sql.rowset.CachedRowSet; public class CachedRowSetReader implements RowSetReader { @@ -39,14 +40,29 @@ } public void readData(RowSetInternal theCaller) throws SQLException { + int pageSize = ((CachedRowSet)theCaller).getPageSize(); ArrayList data = new ArrayList(); - int columnCount = metadata.getColumnCount(); - while (rs.next()) { + int columnCount = metadata.getColumnCount(); + int tempCursor = 0; + + if (startRow >= 0) { + if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) + throw new SQLException(); + else { + rs.beforeFirst(); + for (int j = 1; j++ < startRow; rs.next()) + ; + } + } + + while ((rs.next())) { Object[] columnData = new Object[columnCount]; for (int i = 0; i < columnCount; i++) { columnData[i] = rs.getObject(i+1); } - data.add(new CachedRow(columnData)); + if((pageSize>0)&&(pageSize<++tempCursor)) break; + data.add(new CachedRow(columnData)); + } ((CachedRowSetImpl) theCaller).setRows(data, columnCount); } 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=592309&r1=592308&r2=592309&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 Mon Nov 5 22:44:32 2007 @@ -32,6 +32,7 @@ public class CachedRowSetWriter implements RowSetWriter { + private ResultSet primaryKeys; private CachedRowSet originalRowSet; @@ -46,7 +47,7 @@ private String sql; - private int columnCount, keysCount, keyColumnNumber; + private int columnCount; private int signal = 0; @@ -55,18 +56,22 @@ private String keyColumnName, whereStatementForOriginal, whereStatementForCurrent; + public boolean writeData(RowSetInternal theRowSet) throws SQLException { // use an optimistic concurrency control mechanism + initial(theRowSet); // analyse every row and do responsible task. currentRowSet.first(); originalRowSet.first(); - while (currentRowSet.next()) { + do{ // rolling with currentRowSet if (originalRowSet.next()) { // deal with updated or deleted row which need do conflict check - if (checkConflictNotExist()) { - writeRowData(); + if (checkConflictNotExist(originalRowSet)) { + //If all of the values in the data source are already the values to be persisted, + //the method acceptChanges does nothing. + if(!checkConflictNotExist(currentRowSet)) writeRowData(); } else { cleanEnvironment(); throw new SyncProviderException(Messages @@ -79,13 +84,14 @@ // FIXME: need pre-check before insert into database? writeRowData(); } - } + }while (currentRowSet.next()); cleanEnvironment(); + return true; } - - private void initial(RowSetInternal theRowSet) throws SQLException { + + private void initial(RowSetInternal theRowSet) throws SQLException { currentRowSet = (CachedRowSetImpl) theRowSet; // initial environment originalRowSet = (CachedRowSet) currentRowSet.getOriginal(); @@ -96,9 +102,9 @@ primaryKeys = originalConnection.getMetaData().getPrimaryKeys("", currentRowSet.getMetaData().getSchemaName(1), tableName); cachedKeySet.populate(primaryKeys); - keysCount = cachedKeySet.getMetaData().getColumnCount(); } + private void writeRowData() throws SQLException { try { createScriptForWriteBack(); @@ -122,19 +128,21 @@ 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()) { + do{ keyColumnName = cachedKeySet.getString("COLUMN_NAME"); whereStatementForCurrent = whereStatementForCurrent + keyColumnName + " = ? " + " and "; - } + }while (cachedKeySet.next()); whereStatementForCurrent = subStringN(whereStatementForCurrent, 5); @@ -185,12 +193,12 @@ + originalRowSet.getMetaData().getColumnName(i) + ", "; tempSelector = tempSelector.substring(0, tempSelector.length() - 2); sql = "select " + tempSelector + " from " + tableName + " where "; - while (cachedKeySet.next()) { + do { keyColumnName = cachedKeySet.getString("COLUMN_NAME"); whereStatementForOriginal = whereStatementForOriginal + keyColumnName + " = ? " + " and "; whereStatementForOriginal = subStringN(whereStatementForOriginal, 5); - } + } while (cachedKeySet.next()); cachedKeySet.first(); sql = sql + whereStatementForOriginal; } @@ -199,11 +207,11 @@ throws SQLException { cachedKeySet.first(); int i = from+1; - while (cachedKeySet.next()) { + do { keyColumnName = cachedKeySet.getString("COLUMN_NAME"); ((PreparedStatement) statement).setObject(i++, inputRS .getObject(keyColumnName)); - } + } while (cachedKeySet.next()); } private void fillParasOfAllColumn() throws SQLException { @@ -212,7 +220,7 @@ .getObject(i)); } - private boolean checkConflictNotExist() { + private boolean checkConflictNotExist(CachedRowSet crs) { try { createScriptForCheck(); statement = originalConnection.prepareStatement(sql); @@ -222,8 +230,7 @@ // 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)))) + if (!(dataInDB.getObject(i).equals(crs.getObject(i)))) return false; } } @@ -234,7 +241,7 @@ } private void cleanEnvironment() { - try { + try { originalRowSet.close(); originalConnection.close(); cachedKeySet.close(); @@ -246,4 +253,5 @@ } } // end class + } Modified: harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/HYOptimisticProvider.java URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/HYOptimisticProvider.java?rev=592309&r1=592308&r2=592309&view=diff ============================================================================== --- harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/HYOptimisticProvider.java (original) +++ harmony/enhanced/classlib/trunk/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/HYOptimisticProvider.java Mon Nov 5 22:44:32 2007 @@ -30,6 +30,10 @@ private final static int providerGrade = SyncProvider.DATASOURCE_NO_LOCK; + private final static String vendor = "Apache Harmony"; + + private final static String version = ""; + @Override public int getDataSourceLock() throws SyncProviderException { // TODO Auto-generated method stub @@ -58,14 +62,12 @@ @Override public String getVendor() { - // TODO Auto-generated method stub - return null; + return vendor; } @Override public String getVersion() { - // TODO Auto-generated method stub - return null; + return version; } @Override 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=592309&r1=592308&r2=592309&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 Mon Nov 5 22:44:32 2007 @@ -22,6 +22,7 @@ import java.sql.SQLException; import java.sql.Statement; +import javax.sql.RowSetMetaData; import javax.sql.rowset.CachedRowSet; import junit.framework.TestCase; @@ -29,6 +30,7 @@ public class CachedRowSetImplTest extends TestCase { 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; @@ -42,84 +44,80 @@ public void setUp() throws IllegalAccessException, InstantiationException, ClassNotFoundException, SQLException { Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); + try { conn = DriverManager.getConnection(DERBY_URL); } catch (SQLException e) { try { - conn = DriverManager.getConnection(DERBY_URL_Create); - } catch (SQLException ee) { + conn = DriverManager.getConnection(DERBY_URL_Create); + } catch (SQLException ee) { throw new SQLException("Create DB Failure!"); - } - }; + } + } + ; + st = conn.createStatement(); + rs = conn.getMetaData().getTables(null, "APP", "USER_INFO", null); - //careful: Integer, rather than int! + // careful: Integer, rather than int! + if (!rs.next()) { st .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(); + + "com.sun.rowset.CachedRowSetImpl").newInstance(); + System.out.println("Testing RI"); } catch (ClassNotFoundException e) { -// System.setProperty("CachedRowSetImpl_Test_Signal", -// "Testing Harmony"); + crset = (CachedRowSet) Class.forName( "org.apache.harmony.sql.internal.rowset.CachedRowSetImpl") .newInstance(); + + System.setProperty("Testing Harmony", "true"); System.out.println("Testing Harmony"); + } crset.populate(rs); rs = st.executeQuery("select * from USER_INFO"); + crset.setUrl(DERBY_URL); } public void tearDown() throws SQLException { if (rs != null) { rs.close(); } + if (crset != null) + crset.close(); } public void testSetSyncProvider() throws Exception { - // String mySyncProvider = "org.apache.internal.SyncProviderImpl"; - // crset.setSyncProvider(mySyncProvider); - // assertEquals(crset.getSyncProvider().getClass().getCanonicalName(), - // mySyncProvider); + if (System.getProperty("Testing Harmony") == "true") { + String mySyncProvider = "org.apache.harmony.sql.internal.rowset.HYOptimisticProvider"; + crset.setSyncProvider(mySyncProvider); + assertEquals(crset.getSyncProvider().getClass().getCanonicalName(), + mySyncProvider); + } } public void testColumnUpdatedInt() throws SQLException { crset.first(); -// try { -// assertFalse(crset.columnUpdated(1)); -// fail("should throw SQLException"); -// } catch (SQLException e) { -// // expected; -// } + // try { + // assertFalse(crset.columnUpdated(1)); + // fail("should throw SQLException"); + // } catch (SQLException e) { + // // expected; + // } crset.next(); try { crset.columnUpdated(-1); @@ -138,12 +136,12 @@ public void testColumnUpdatedString() throws SQLException { crset.first(); -// try { -// assertFalse(crset.columnUpdated("ID")); -// fail("should throw SQLException"); -// } catch (SQLException e) { -// // expected; -// } + // try { + // assertFalse(crset.columnUpdated("ID")); + // fail("should throw SQLException"); + // } catch (SQLException e) { + // // expected; + // } crset.next(); try { assertFalse(crset.columnUpdated("Incorrect")); @@ -172,7 +170,8 @@ assertEquals(Integer.MAX_VALUE, crset.getPageSize()); } - public void testGetTableName() throws SQLException { + public void testGetTableName() throws SQLException { + crset.setTableName("USER"); assertEquals("USER", crset.getTableName()); } @@ -192,12 +191,12 @@ public void testDeleteRow() throws SQLException { crset.first(); -// try { -// crset.deleteRow(); -// fail("should throw SQLException"); -// } catch (SQLException e) { -// // expected; -// } + // try { + // crset.deleteRow(); + // fail("should throw SQLException"); + // } catch (SQLException e) { + // // expected; + // } crset.next(); assertFalse(crset.rowDeleted()); crset.deleteRow(); @@ -206,12 +205,12 @@ } 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 { @@ -237,55 +236,229 @@ assertEquals("TonyWu", crset.getString("Name")); assertEquals(3, crset.getInt(1)); assertEquals(3, crset.getInt("ID")); - //FIXME - //The value returned depends on whether or not this ResultSet object can detect visible inserts. - // It depends on implementation?? -// assertTrue(crset.rowInserted()); + + crset.moveToCurrentRow(); + assertFalse(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(); + crset.first(); + assertEquals(1, crset.getInt(1)); + assertEquals("hermit", crset.getString(2)); crset.updateString(2, "HarmonY"); - + crset.moveToInsertRow(); crset.updateInt(1, 16); - crset.updateString(2, "Apache"); + crset.updateString(2, "Apache"); crset.insertRow(); crset.moveToCurrentRow(); - + crset.deleteRow(); - + /* + * RI will print the change result + */ + crset.acceptChanges(); + + rs = st.executeQuery("select * from USER_INFO"); + rs.next(); + assertEquals(rs.getString(2), "test"); + rs.next(); + assertEquals(rs.getString(2), "Apache"); + + } + + public void testExecute() throws SQLException { + crset.setCommand("Update User_INFO set Name= ? Where ID= ? "); + crset.setString(1, "executed!"); + crset.setInt(2, 1); + crset.execute(); + + crset.setCommand("SELECT ID, NAME FROM USER_INFO" + " WHERE ID = ? "); + crset.setInt(1, 1); + crset.execute(); + + crset.first(); + assertEquals("executed!", crset.getString(2)); + + crset.setCommand("Update User_INFO set Name= ? Where ID= ? "); + crset.setString(1, "executed!"); + crset.setInt(2, 1); + crset.execute(DriverManager.getConnection(DERBY_URL)); + + crset.setCommand("SELECT ID, NAME FROM USER_INFO" + " WHERE ID = ? "); + crset.setInt(1, 1); + crset.execute(DriverManager.getConnection(DERBY_URL)); + } + + public void testExecute2() throws Exception { + crset.setCommand("SELECT ID, NAME FROM USER_INFO" + " WHERE ID = ? "); + crset.setInt(1, 1); + crset.execute(); + + crset.first(); + assertEquals("hermit", crset.getString(2)); + } + + public void testCreateShared() throws Exception { + CachedRowSet crsetShared = (CachedRowSet) crset.createShared(); + crsetShared.first(); + crset.first(); + crsetShared.updateString(2, "copyTest2"); + assertEquals(crsetShared.getString(2), "copyTest2"); + assertEquals(crset.getString(2), "copyTest2"); + } + + public void testcreateCopyNoConstraints() throws Exception { + crset.first(); + + CachedRowSet crsetCopyNoConstraints = (CachedRowSet) crset + .createCopyNoConstraints(); + + // Modify he constraints + crset.setReadOnly(false); + crset.setConcurrency(ResultSet.CONCUR_READ_ONLY); + crset.setType(ResultSet.TYPE_FORWARD_ONLY); + + crsetCopyNoConstraints.first(); + crsetCopyNoConstraints.updateString(2, "copyTest2"); + assertEquals(crsetCopyNoConstraints.getString(2), "copyTest2"); + assertEquals(crset.getString(2), "hermit"); + // the copyNoConstraints keep the default value of the CachedRowSet + assertEquals(crsetCopyNoConstraints.isReadOnly(), true); + assertEquals(crsetCopyNoConstraints.getConcurrency(), + ResultSet.CONCUR_UPDATABLE); + assertEquals(crsetCopyNoConstraints.getType(), + ResultSet.TYPE_SCROLL_INSENSITIVE); + + } + + public void testCopySchema() throws Exception { + crset.first(); + CachedRowSet crsetCopySchema = (CachedRowSet) crset.createCopySchema(); + + RowSetMetaData rsmCopySchema = (RowSetMetaData) crsetCopySchema + .getMetaData(); + assertEquals("USER_INFO", rsmCopySchema.getTableName(1)); + assertEquals(2, rsmCopySchema.getColumnCount()); + + RowSetMetaData rsm = (RowSetMetaData) crset.getMetaData(); + rsm.setTableName(1, "newBorn"); + assertEquals("newBorn", rsm.getTableName(1)); + + crset.setTableName("test"); + assertEquals("test", crset.getTableName()); + } + + public void testCreateCopy() throws Exception { + crset.first(); + assertEquals(crset.getString(2), "hermit"); + crset.updateString(2, "copyTest"); + crset.updateRow(); + crset.acceptChanges(); + + rs = st.executeQuery("select * from USER_INFO"); + rs.next(); + assertEquals(rs.getString(2), "copyTest"); + + CachedRowSet crsetCopy = (CachedRowSet) crset.createCopy(); + + crsetCopy.first(); + crsetCopy.updateString(2, "copyTest2"); + crsetCopy.updateRow(); + crsetCopy.acceptChanges(); + + assertEquals(crsetCopy.getString(2), "copyTest2"); + assertEquals(crset.getString(2), "copyTest"); + + rs = st.executeQuery("select * from USER_INFO"); + rs.next(); + assertEquals(rs.getString(2), "copyTest2"); + + crset.first(); + assertEquals(crset.getString(2), "copyTest"); + } + + public void testAfterLast() throws Exception { 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(); + rs.afterLast(); + fail("Should throw SQLException"); } catch (SQLException e) { - fail("should throw SyncProviderException"); + // expected + } + + crset.afterLast(); + crset.previous(); + assertEquals(2, crset.getInt(1)); + } + + public void testNextandPreviousPage() throws Exception { + + st.executeUpdate("delete from USER_INFO"); + st.executeUpdate("insert into USER_INFO(ID,NAME) values (1,'1')"); + st.executeUpdate("insert into USER_INFO(ID,NAME) values (2,'2')"); + st.executeUpdate("insert into USER_INFO(ID,NAME) values (3,'3')"); + st.executeUpdate("insert into USER_INFO(ID,NAME) values (4,'4')"); + rs = st.executeQuery("select * from USER_INFO"); + + crset.setPageSize(2); + crset.setCommand("SELECT ID FROM USER_INFO"); + crset.execute(); + + for (int j = 0; j < 2; j++) + crset.next(); + assertFalse(crset.next()); + + int i = 0; + + crset.beforeFirst(); + while (crset.nextPage()) { + while (crset.next()) { + assertEquals(++i, crset.getInt(1)); + } + } + + while (crset.previousPage()) { + crset.afterLast(); + while (crset.previous()) { + assertEquals(i--, crset.getInt(1)); + } + } + + while (crset.previousPage()) { + i = i - crset.getPageSize(); + int j = i; + while (crset.next()) { + assertEquals(++j, crset.getInt(1)); + } } } -// 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)); -// } + public void testPopulate() throws Exception { + CachedRowSet cc = crset.createCopy(); + + try { + crset.populate(rs, 0); + fail("should throw exception"); + } catch (Exception e) { + // expected + } + crset.populate(rs); + crset.first(); + assertEquals("hermit", crset.getString(2)); + + crset.populate(cc, 2); + crset.first(); + assertEquals("test", crset.getString(2)); + + crset.populate(cc, 1); + crset.first(); + assertEquals("hermit", crset.getString(2)); + } }