0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017: package org.apache.harmony.sql.internal.rowset;
0018:
0019: import java.io.InputStream;
0020: import java.io.Reader;
0021: import java.lang.reflect.Field;
0022: import java.math.BigDecimal;
0023: import java.sql.Array;
0024: import java.sql.Blob;
0025: import java.sql.Clob;
0026: import java.sql.Connection;
0027: import java.sql.Date;
0028: import java.sql.DriverManager;
0029: import java.sql.PreparedStatement;
0030: import java.sql.Ref;
0031: import java.sql.ResultSet;
0032: import java.sql.ResultSetMetaData;
0033: import java.sql.SQLException;
0034: import java.sql.SQLWarning;
0035: import java.sql.Savepoint;
0036: import java.sql.Statement;
0037: import java.sql.Time;
0038: import java.sql.Timestamp;
0039: import java.util.ArrayList;
0040: import java.util.Calendar;
0041: import java.util.Collection;
0042: import java.util.HashMap;
0043: import java.util.Hashtable;
0044: import java.util.Map;
0045: import java.util.Vector;
0046:
0047: import javax.sql.RowSet;
0048: import javax.sql.RowSetEvent;
0049: import javax.sql.RowSetInternal;
0050: import javax.sql.RowSetListener;
0051: import javax.sql.RowSetMetaData;
0052: import javax.sql.rowset.BaseRowSet;
0053: import javax.sql.rowset.CachedRowSet;
0054: import javax.sql.rowset.RowSetMetaDataImpl;
0055: import javax.sql.rowset.RowSetWarning;
0056: import javax.sql.rowset.spi.SyncFactory;
0057: import javax.sql.rowset.spi.SyncFactoryException;
0058: import javax.sql.rowset.spi.SyncProvider;
0059: import javax.sql.rowset.spi.SyncProviderException;
0060:
0061: import org.apache.harmony.luni.util.NotImplementedException;
0062: import org.apache.harmony.sql.internal.nls.Messages;
0063:
0064: public class CachedRowSetImpl extends BaseRowSet implements
0065: CachedRowSet, RowSetInternal {
0066:
0067: private static final long serialVersionUID = 1L;
0068:
0069: private ArrayList<CachedRow> rows;
0070:
0071: private RowSetMetaData meta;
0072:
0073: private CachedRow currentRow;
0074:
0075: // start from : 1.
0076: private int currentRowIndex;
0077:
0078: // the number of the rows in one "page"
0079: private int pageSize;
0080:
0081: private int pageNumber = 1;
0082:
0083: private String tableName;
0084:
0085: private int rememberedCursorPosition;
0086:
0087: private CachedRow insertRow;
0088:
0089: // TODO remember to evalute it in CachedRowSetReader
0090: private int[] keyCols;
0091:
0092: private int columnCount;
0093:
0094: private SyncProvider syncProvider;
0095:
0096: // TODO where is it initialized
0097: private CachedRowSetImpl originalResultSet;
0098:
0099: private Object currentColumn;
0100:
0101: private SQLWarning sqlwarn;
0102:
0103: public CachedRowSetImpl(String providerID)
0104: throws SyncFactoryException {
0105: syncProvider = SyncFactory.getInstance(providerID);
0106: initialProperties();
0107: }
0108:
0109: private void initialProperties() {
0110: try {
0111: setEscapeProcessing(true);
0112: setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
0113: setConcurrency(ResultSet.CONCUR_UPDATABLE);
0114: setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
0115: setMaxRows(0);
0116: setQueryTimeout(0);
0117: setShowDeleted(false);
0118: setUsername(null);
0119: setPassword(null);
0120: setMaxFieldSize(0);
0121: setTypeMap(null);
0122: setFetchSize(0);
0123: } catch (SQLException e) {
0124: // ignore, never reached
0125: }
0126:
0127: }
0128:
0129: public CachedRowSetImpl() throws SyncFactoryException {
0130: this ("Apache Harmony HYOptimisticProvider");
0131: }
0132:
0133: public void setRows(ArrayList<CachedRow> data, int cloumnCount) {
0134: rows = data;
0135: this .columnCount = cloumnCount;
0136: }
0137:
0138: public void acceptChanges() throws SyncProviderException {
0139: if (currentRow == insertRow && currentRow != null) {
0140: throw new SyncProviderException();
0141: }
0142:
0143: try {
0144: acceptChanges(getConnection());
0145: } catch (SQLException e) {
0146: // FIXME deal with the exception, not just print it
0147: e.printStackTrace();
0148: }
0149: }
0150:
0151: public void acceptChanges(Connection con)
0152: throws SyncProviderException {
0153: if (currentRow == insertRow && currentRow != null) {
0154: // TODO add error messages
0155: throw new SyncProviderException();
0156: }
0157:
0158: try {
0159: CachedRowSetWriter rowSetWriter = (CachedRowSetWriter) syncProvider
0160: .getRowSetWriter();
0161: rowSetWriter.setConnection(con);
0162: int beforeWriteIndex = currentRowIndex;
0163: rowSetWriter.writeData(this );
0164: absolute(beforeWriteIndex);
0165: /*
0166: * FIXME: if no conflicts happen when writeData, then call
0167: * setOriginalRow()
0168: */
0169: notifyRowSetChanged();
0170:
0171: } catch (SyncProviderException e) {
0172: throw e;
0173: } catch (SQLException e) {
0174: throw new SyncProviderException(e.getMessage());
0175: }
0176: }
0177:
0178: public boolean columnUpdated(int idx) throws SQLException {
0179: if (currentRow == null || idx > meta.getColumnCount()) {
0180: // rowset.0 = Not a valid position
0181: throw new SQLException(Messages.getString("rowset.0"));
0182: }
0183: return currentRow.getUpdateMask(idx - 1);
0184: }
0185:
0186: public boolean columnUpdated(String columnName) throws SQLException {
0187: return columnUpdated(getIndexByName(columnName));
0188: }
0189:
0190: private int getIndexByName(String columnName) throws SQLException {
0191: for (int i = 1; i <= meta.getColumnCount(); i++) {
0192: if (columnName.equalsIgnoreCase(meta.getColumnName(i))) {
0193: return i;
0194: }
0195: }
0196: // rowset.1=Not a valid column name
0197: throw new SQLException(Messages.getString("rowset.1"));
0198: }
0199:
0200: public void commit() throws SQLException {
0201: getConnection().commit();
0202: }
0203:
0204: public CachedRowSet createCopy() throws SQLException {
0205: CachedRowSetImpl output;
0206: try {
0207: /*
0208: * the attribute of BaseRowSet which are needed to deep copy
0209: */
0210: // BaseRowSet.params <Hashtable>
0211: Object[] paramsObjArray = super .getParams().clone();
0212: Hashtable<Object, Object> paramsHashtable = new Hashtable<Object, Object>();
0213: for (int i = 0; i < paramsObjArray.length; i++) {
0214: paramsHashtable.put(Integer.valueOf(i),
0215: paramsObjArray[i]);
0216: }
0217: // BaseRowSet.listeners <Vector>
0218: Vector<RowSetListener> listeners = new Vector<RowSetListener>();
0219:
0220: /*
0221: * deep copy BaseRowSet
0222: */
0223: output = (CachedRowSetImpl) super .clone();
0224: // BaseRowSet.params
0225: Field paramsField = output.getClass().getSuperclass()
0226: .getDeclaredField("params");
0227: paramsField.setAccessible(true);
0228: paramsField.set(output, paramsHashtable);
0229: // BaseRowSet.listeners
0230: Field listenersField = output.getClass().getSuperclass()
0231: .getDeclaredField("listeners");
0232: listenersField.setAccessible(true);
0233: listenersField.set(output, listeners);
0234: // BaseRowSet.map
0235: if (super .getTypeMap() != null) {
0236: Map<String, Class<?>> originalTypeMap = super
0237: .getTypeMap();
0238: Map<String, Class<?>> copyTypeMap = new HashMap<String, Class<?>>();
0239: copyTypeMap.putAll(originalTypeMap);
0240: output.setTypeMap(copyTypeMap);
0241: }
0242:
0243: /*
0244: * deep copy CachedRowSetImpl
0245: */
0246: // CachedRowSetImpl.rows <ArrayList>
0247: ArrayList<CachedRow> copyRows = new ArrayList<CachedRow>();
0248: for (int i = 0; i < rows.size(); i++) {
0249: copyRows.add(rows.get(i).createClone());
0250: }
0251: output.setRows(copyRows, columnCount);
0252: // CachedRowSetImpl.meta <RowSetMetaData>
0253: output.setMetaData(copyMetaData(getMetaData()));
0254: // set currentRow
0255: if ((currentRowIndex > 0)
0256: && (currentRowIndex <= rows.size())) {
0257: output.absolute(currentRowIndex);
0258: }
0259: // others
0260: if (getKeyColumns() != null) {
0261: output.setKeyColumns(getKeyColumns().clone());
0262: }
0263: // CachedRowSetImpl.originalResultSet
0264: CachedRowSetImpl copyOriginalRs = new CachedRowSetImpl();
0265: copyOriginalRs.populate(getOriginal());
0266: output.originalResultSet = copyOriginalRs;
0267:
0268: /*
0269: * TODO uncomment after getMatchColumnIndexes and
0270: * getMatchColumnNames implemented
0271: */
0272: // if (getMatchColumnIndexes() != null) {
0273: // output.setMatchColumn(getMatchColumnIndexes().clone());
0274: // }
0275: // if (getMatchColumnNames() != null) {
0276: // output.setMatchColumn(getMatchColumnNames().clone());
0277: // }
0278: output.setSyncProvider(getSyncProvider().getProviderID());
0279: if (insertRow != null) {
0280: output.insertRow = insertRow.createClone();
0281: }
0282:
0283: return output;
0284: } catch (CloneNotSupportedException e) {
0285: // TODO add error message
0286: throw new SQLException();
0287: } catch (NoSuchFieldException e) {
0288: // TODO add error message
0289: throw new SQLException();
0290: } catch (IllegalAccessException e) {
0291: // TODO add error message
0292: throw new SQLException();
0293: }
0294: }
0295:
0296: public CachedRowSet createCopyNoConstraints() throws SQLException {
0297: CachedRowSetImpl output = (CachedRowSetImpl) createCopy();
0298: output.initialProperties();
0299: return output;
0300: }
0301:
0302: public CachedRowSet createCopySchema() throws SQLException {
0303: CachedRowSetImpl output = (CachedRowSetImpl) createCopy();
0304:
0305: // clean up rows data
0306: output.currentColumn = null;
0307: output.currentRow = null;
0308: output.currentRowIndex = 0;
0309: output.insertRow = null;
0310: output.pageNumber = 1;
0311: output.rememberedCursorPosition = 0;
0312: output.rows = new ArrayList<CachedRow>();
0313: output.sqlwarn = null;
0314:
0315: return output;
0316: }
0317:
0318: public RowSet createShared() throws SQLException {
0319: // shallow copy
0320: RowSet result = null;
0321: try {
0322: result = (RowSet) super .clone();
0323: } catch (CloneNotSupportedException e) {
0324: // TODO add error message
0325: throw new SQLException();
0326: }
0327:
0328: return result;
0329: }
0330:
0331: public void execute(Connection conn) throws SQLException {
0332: // ensure the getConnection can works!
0333: String localCommand = getCommand();
0334: if (localCommand == null || getParams() == null) {
0335: // TODO add error messages
0336: throw new SQLException();
0337: }
0338:
0339: PreparedStatement ps = conn.prepareStatement(localCommand);
0340: Object[] params = getParams();
0341: for (int i = 0; i < params.length; i++)
0342: ps.setObject(i + 1, params[i]);
0343:
0344: if (ps.execute()) {
0345: doPopulate(ps.getResultSet(), true);
0346: }
0347: }
0348:
0349: public int[] getKeyColumns() throws SQLException {
0350: return keyCols == null ? null : keyCols.clone();
0351: }
0352:
0353: public ResultSet getOriginal() throws SQLException {
0354: return originalResultSet;
0355: }
0356:
0357: public ResultSet getOriginalRow() throws SQLException {
0358: if (currentRow == null) {
0359: // TODO add error messages
0360: throw new SQLException();
0361: }
0362:
0363: CachedRowSetImpl originalRowRset = new CachedRowSetImpl();
0364: ArrayList<CachedRow> data = new ArrayList<CachedRow>();
0365: CachedRow originalCachedRow = rows.get(getRow() - 1)
0366: .getOriginal();
0367: data.add(originalCachedRow);
0368: originalRowRset.setRows(data, columnCount);
0369: originalRowRset.setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
0370: originalRowRset.setConcurrency(ResultSet.CONCUR_UPDATABLE);
0371: return originalRowRset;
0372: }
0373:
0374: public int getPageSize() {
0375: return pageSize;
0376: }
0377:
0378: public RowSetWarning getRowSetWarnings() throws SQLException {
0379: throw new NotImplementedException();
0380: }
0381:
0382: public SyncProvider getSyncProvider() throws SQLException {
0383: return syncProvider;
0384: }
0385:
0386: public String getTableName() throws SQLException {
0387: return tableName;
0388: }
0389:
0390: /**
0391: * TODO refill the cachedrowset with pagesize, and the previous rowset was
0392: * replaced
0393: */
0394: public boolean nextPage() throws SQLException {
0395: pageNumber++;
0396: return false;
0397: }
0398:
0399: public void populate(ResultSet rs) throws SQLException {
0400: doPopulate(rs, false);
0401: }
0402:
0403: public void populate(ResultSet rs, int startRow)
0404: throws SQLException {
0405: if (startRow == 1) {
0406: rs.beforeFirst();
0407: } else if (startRow <= 0 || !rs.absolute(startRow - 1)) {
0408: // rowset.7=Not a valid cursor
0409: throw new SQLException(Messages.getString("rowset.7")); //$NON-NLS-1$
0410: }
0411:
0412: doPopulate(rs, true);
0413: }
0414:
0415: private void doPopulate(ResultSet rs, boolean isPaging)
0416: throws SQLException {
0417: meta = copyMetaData(rs.getMetaData());
0418:
0419: /*
0420: * this method not support paging, so before readData set pageSize and
0421: * maxRowsto 0 and restore previous values after readData
0422: */
0423: if (!isPaging) {
0424: int prePageSize = getPageSize();
0425: setPageSize(0);
0426: int preMaxRows = getMaxRows();
0427: setMaxRows(0);
0428: // FIXME use SyncProvider to get RowSetReader
0429: new CachedRowSetReader(rs).readData(this );
0430: setPageSize(prePageSize);
0431: setMaxRows(preMaxRows);
0432: } else {
0433: // FIXME use SyncProvider to get RowSetReader
0434: new CachedRowSetReader(rs).readData(this );
0435: }
0436:
0437: setTableName(rs.getMetaData().getTableName(1));
0438:
0439: originalResultSet = new CachedRowSetImpl();
0440: // FIXME use SyncProvider to get RowSetReader
0441: new CachedRowSetReader(this ).readData(originalResultSet);
0442: originalResultSet.setMetaData((RowSetMetaData) (getMetaData()));
0443:
0444: // recovery the states
0445: beforeFirst();
0446: }
0447:
0448: // deep copy of ResultSetMetaData
0449: private RowSetMetaData copyMetaData(ResultSetMetaData metaData)
0450: throws SQLException {
0451: RowSetMetaDataImpl rowSetMetaData = new RowSetMetaDataImpl();
0452: rowSetMetaData.setColumnCount(metaData.getColumnCount());
0453: for (int columnIndex = 1; columnIndex <= metaData
0454: .getColumnCount(); columnIndex++) {
0455: rowSetMetaData.setAutoIncrement(columnIndex, metaData
0456: .isAutoIncrement(columnIndex));
0457: rowSetMetaData.setCaseSensitive(columnIndex, metaData
0458: .isCaseSensitive(columnIndex));
0459: rowSetMetaData.setCatalogName(columnIndex, metaData
0460: .getCatalogName(columnIndex));
0461: rowSetMetaData.setColumnDisplaySize(columnIndex, metaData
0462: .getColumnDisplaySize(columnIndex));
0463: rowSetMetaData.setColumnLabel(columnIndex, metaData
0464: .getColumnLabel(columnIndex));
0465: rowSetMetaData.setColumnName(columnIndex, metaData
0466: .getColumnName(columnIndex));
0467: rowSetMetaData.setColumnType(columnIndex, metaData
0468: .getColumnType(columnIndex));
0469: rowSetMetaData.setColumnTypeName(columnIndex, metaData
0470: .getColumnTypeName(columnIndex));
0471: rowSetMetaData.setCurrency(columnIndex, metaData
0472: .isCurrency(columnIndex));
0473: rowSetMetaData.setNullable(columnIndex, metaData
0474: .isNullable(columnIndex));
0475: rowSetMetaData.setPrecision(columnIndex, metaData
0476: .getPrecision(columnIndex));
0477: rowSetMetaData.setScale(columnIndex, metaData
0478: .getScale(columnIndex));
0479: rowSetMetaData.setSchemaName(columnIndex, metaData
0480: .getSchemaName(columnIndex));
0481: rowSetMetaData.setSearchable(columnIndex, metaData
0482: .isSearchable(columnIndex));
0483: rowSetMetaData.setSigned(columnIndex, metaData
0484: .isSigned(columnIndex));
0485: rowSetMetaData.setTableName(columnIndex, metaData
0486: .getTableName(columnIndex));
0487: }
0488: return rowSetMetaData;
0489: }
0490:
0491: public boolean previousPage() throws SQLException {
0492: // TODO implement it
0493: return false;
0494: }
0495:
0496: public void release() throws SQLException {
0497: throw new NotImplementedException();
0498: }
0499:
0500: public void restoreOriginal() throws SQLException {
0501: throw new NotImplementedException();
0502: }
0503:
0504: public void rollback() throws SQLException {
0505: throw new NotImplementedException();
0506: }
0507:
0508: public void rollback(Savepoint s) throws SQLException {
0509: throw new NotImplementedException();
0510: }
0511:
0512: public void rowSetPopulated(RowSetEvent event, int numRows)
0513: throws SQLException {
0514: throw new NotImplementedException();
0515: }
0516:
0517: public void setKeyColumns(int[] keys) throws SQLException {
0518: keyCols = keys.clone();
0519: }
0520:
0521: public void setMetaData(RowSetMetaData md) throws SQLException {
0522: meta = md;
0523: }
0524:
0525: public void setOriginalRow() throws SQLException {
0526:
0527: // FIXME re-implements this method
0528: if (currentRow == null) {
0529: // TODO add error messages
0530: throw new SQLException();
0531: }
0532: currentRow.setNonUpdateable();
0533: }
0534:
0535: public void setPageSize(int size) throws SQLException {
0536: if (size < 0) {
0537: // rowset.2=Negative page size
0538: throw new SQLException(Messages.getString("rowset.2"));
0539: }
0540: if ((getMaxRows() != 0) && (getMaxRows() < size)) {
0541: // rowset.9=PageSize can not larger than MaxRows
0542: throw new SQLException(Messages.getString("rowset.9"));
0543: }
0544: pageSize = size;
0545: }
0546:
0547: public void setSyncProvider(String provider) throws SQLException {
0548: syncProvider = SyncFactory.getInstance(provider);
0549: }
0550:
0551: public void setTableName(String tabName) throws SQLException {
0552: if (tabName == null) {
0553: // rowset.3=Table name should not be null
0554: throw new SQLException("rowset.3");
0555: }
0556: tableName = tabName;
0557: }
0558:
0559: public int size() {
0560: if (rows == null) {
0561: return 0;
0562: }
0563: return rows.size();
0564: }
0565:
0566: public Collection<?> toCollection() throws SQLException {
0567: throw new NotImplementedException();
0568: }
0569:
0570: public Collection<?> toCollection(int column) throws SQLException {
0571: throw new NotImplementedException();
0572: }
0573:
0574: public Collection<?> toCollection(String column)
0575: throws SQLException {
0576: throw new NotImplementedException();
0577: }
0578:
0579: public void undoDelete() throws SQLException {
0580: if (currentRow == null) {
0581: // TODO add error messages
0582: throw new SQLException();
0583: }
0584: if (currentRow.isDelete()) {
0585: currentRow.undoDelete();
0586: }
0587: }
0588:
0589: public void undoInsert() throws SQLException {
0590: throw new NotImplementedException();
0591: }
0592:
0593: public void undoUpdate() throws SQLException {
0594: throw new NotImplementedException();
0595: }
0596:
0597: public int[] getMatchColumnIndexes() throws SQLException {
0598: throw new NotImplementedException();
0599: }
0600:
0601: public String[] getMatchColumnNames() throws SQLException {
0602: throw new NotImplementedException();
0603: }
0604:
0605: public void setMatchColumn(int columnIdx) throws SQLException {
0606: throw new NotImplementedException();
0607: }
0608:
0609: public void setMatchColumn(int[] columnIdxes) throws SQLException {
0610: throw new NotImplementedException();
0611: }
0612:
0613: public void setMatchColumn(String columnName) throws SQLException {
0614: throw new NotImplementedException();
0615: }
0616:
0617: public void setMatchColumn(String[] columnNames)
0618: throws SQLException {
0619: throw new NotImplementedException();
0620: }
0621:
0622: public void unsetMatchColumn(int columnIdx) throws SQLException {
0623: throw new NotImplementedException();
0624: }
0625:
0626: public void unsetMatchColumn(int[] columnIdxes) throws SQLException {
0627: throw new NotImplementedException();
0628: }
0629:
0630: public void unsetMatchColumn(String columnName) throws SQLException {
0631: throw new NotImplementedException();
0632: }
0633:
0634: public void unsetMatchColumn(String[] columnName)
0635: throws SQLException {
0636: throw new NotImplementedException();
0637: }
0638:
0639: public boolean absolute(int row) throws SQLException {
0640: return doAbsolute(row, true);
0641: }
0642:
0643: /**
0644: * internal implement of absolute
0645: *
0646: * @param row
0647: * index of row cursor to move
0648: * @param checkType
0649: * whether to check property ResultSet.TYPE_FORWARD_ONLY
0650: * @return whether the cursor is on result set
0651: * @throws SQLException
0652: */
0653: private boolean doAbsolute(int row, boolean checkType)
0654: throws SQLException {
0655: if (rows == null || rows.size() == 0) {
0656: return false;
0657: }
0658:
0659: if (checkType && getType() == ResultSet.TYPE_FORWARD_ONLY) {
0660: // rowset.8=The Result Set Type is TYPE_FORWARD_ONLY
0661: throw new SQLException(Messages.getString("rowset.8"));
0662: }
0663:
0664: if (row < 0) {
0665: row = rows.size() + row + 1;
0666: }
0667:
0668: if (row <= 0) {
0669: currentRowIndex = 0;
0670: currentRow = null;
0671: return false;
0672: }
0673:
0674: if (row > rows.size()) {
0675: currentRowIndex = rows.size() + 1;
0676: currentRow = null;
0677: return false;
0678: }
0679:
0680: currentRowIndex = row;
0681: currentRow = rows.get(currentRowIndex - 1);
0682: return true;
0683: }
0684:
0685: public void afterLast() throws SQLException {
0686: if (rows == null) {
0687: return;
0688: }
0689:
0690: doAbsolute(rows.size() + 1, true);
0691: }
0692:
0693: public void beforeFirst() throws SQLException {
0694: doAbsolute(0, true);
0695: }
0696:
0697: public void cancelRowUpdates() throws SQLException {
0698: throw new NotImplementedException();
0699: }
0700:
0701: public void clearWarnings() throws SQLException {
0702: throw new NotImplementedException();
0703: }
0704:
0705: public void close() throws SQLException {
0706:
0707: // TODO need more concerns!
0708: if (rows != null) {
0709: rows.clear();
0710: }
0711: currentRowIndex = 0;
0712: currentRow = null;
0713: meta = null;
0714:
0715: }
0716:
0717: public void deleteRow() throws SQLException {
0718: checkValidRow();
0719: currentRow.setDelete();
0720: }
0721:
0722: private void checkValidRow() throws SQLException {
0723: if (currentRow == null) {
0724: // rowset.0 = Not a valid position
0725: throw new SQLException(Messages.getString("rowset.0"));
0726: }
0727: }
0728:
0729: public int findColumn(String columnName) throws SQLException {
0730: throw new NotImplementedException();
0731: }
0732:
0733: public boolean first() throws SQLException {
0734: return doAbsolute(1, true);
0735: }
0736:
0737: public Array getArray(int columnIndex) throws SQLException {
0738: throw new NotImplementedException();
0739: }
0740:
0741: public Array getArray(String colName) throws SQLException {
0742: throw new NotImplementedException();
0743: }
0744:
0745: public InputStream getAsciiStream(int columnIndex)
0746: throws SQLException {
0747: throw new NotImplementedException();
0748: }
0749:
0750: public InputStream getAsciiStream(String columnName)
0751: throws SQLException {
0752: throw new NotImplementedException();
0753: }
0754:
0755: public BigDecimal getBigDecimal(int columnIndex)
0756: throws SQLException {
0757: throw new NotImplementedException();
0758: }
0759:
0760: public BigDecimal getBigDecimal(int columnIndex, int scale)
0761: throws SQLException {
0762: throw new NotImplementedException();
0763: }
0764:
0765: public BigDecimal getBigDecimal(String columnName)
0766: throws SQLException {
0767: throw new NotImplementedException();
0768: }
0769:
0770: public BigDecimal getBigDecimal(String columnName, int scale)
0771: throws SQLException {
0772: throw new NotImplementedException();
0773: }
0774:
0775: public InputStream getBinaryStream(int columnIndex)
0776: throws SQLException {
0777: throw new NotImplementedException();
0778: }
0779:
0780: public InputStream getBinaryStream(String columnName)
0781: throws SQLException {
0782: throw new NotImplementedException();
0783: }
0784:
0785: public Blob getBlob(int columnIndex) throws SQLException {
0786: checkValidRow();
0787: Object value = currentRow.getObject(columnIndex);
0788: if (value == null) {
0789: return null;
0790: }
0791: return (Blob) value;
0792: }
0793:
0794: public Blob getBlob(String columnName) throws SQLException {
0795: return getBlob(getIndexByName(columnName));
0796: }
0797:
0798: public boolean getBoolean(int columnIndex) throws SQLException {
0799: checkValidRow();
0800: Object value = currentRow.getObject(columnIndex);
0801: if (value == null) {
0802: return false;
0803: }
0804: return ((Boolean) value).booleanValue();
0805: }
0806:
0807: public boolean getBoolean(String columnName) throws SQLException {
0808: return getBoolean(getIndexByName(columnName));
0809: }
0810:
0811: public byte getByte(int columnIndex) throws SQLException {
0812: checkValidRow();
0813: Object value = currentRow.getObject(columnIndex);
0814: if (value == null) {
0815: return 0;
0816: }
0817: return ((Byte) value).byteValue();
0818: }
0819:
0820: public byte getByte(String columnName) throws SQLException {
0821: return getByte(getIndexByName(columnName));
0822: }
0823:
0824: public byte[] getBytes(int columnIndex) throws SQLException {
0825: checkValidRow();
0826: Object value = currentRow.getObject(columnIndex);
0827: if (value == null) {
0828: return null;
0829: }
0830: return (byte[]) value;
0831: }
0832:
0833: public byte[] getBytes(String columnName) throws SQLException {
0834: return getBytes(getIndexByName(columnName));
0835: }
0836:
0837: public Reader getCharacterStream(int columnIndex)
0838: throws SQLException {
0839: throw new NotImplementedException();
0840: }
0841:
0842: public Reader getCharacterStream(String columnName)
0843: throws SQLException {
0844: throw new NotImplementedException();
0845: }
0846:
0847: public Clob getClob(int columnIndex) throws SQLException {
0848: throw new NotImplementedException();
0849: }
0850:
0851: public Clob getClob(String colName) throws SQLException {
0852: throw new NotImplementedException();
0853: }
0854:
0855: public String getCursorName() throws SQLException {
0856: throw new NotImplementedException();
0857: }
0858:
0859: public Date getDate(int columnIndex) throws SQLException {
0860: throw new NotImplementedException();
0861: }
0862:
0863: public Date getDate(int columnIndex, Calendar cal)
0864: throws SQLException {
0865: throw new NotImplementedException();
0866: }
0867:
0868: public Date getDate(String columnName) throws SQLException {
0869: throw new NotImplementedException();
0870: }
0871:
0872: public Date getDate(String columnName, Calendar cal)
0873: throws SQLException {
0874: throw new NotImplementedException();
0875: }
0876:
0877: public double getDouble(int columnIndex) throws SQLException {
0878: throw new NotImplementedException();
0879: }
0880:
0881: public double getDouble(String columnName) throws SQLException {
0882: throw new NotImplementedException();
0883: }
0884:
0885: public float getFloat(int columnIndex) throws SQLException {
0886: throw new NotImplementedException();
0887: }
0888:
0889: public float getFloat(String columnName) throws SQLException {
0890: throw new NotImplementedException();
0891: }
0892:
0893: public int getInt(int columnIndex) throws SQLException {
0894: checkValidRow();
0895: Object value = currentRow.getObject(columnIndex);
0896: if (value == null) {
0897: return 0;
0898: }
0899: return ((Integer) value).intValue();
0900: }
0901:
0902: public int getInt(String columnName) throws SQLException {
0903: return getInt(getIndexByName(columnName));
0904: }
0905:
0906: public long getLong(int columnIndex) throws SQLException {
0907: throw new NotImplementedException();
0908: }
0909:
0910: public long getLong(String columnName) throws SQLException {
0911: throw new NotImplementedException();
0912: }
0913:
0914: public ResultSetMetaData getMetaData() throws SQLException {
0915: return meta;
0916: }
0917:
0918: public Object getObject(int columnIndex) throws SQLException {
0919: return currentRow.getObject(columnIndex);
0920: }
0921:
0922: public Object getObject(int columnIndex, Map<String, Class<?>> map)
0923: throws SQLException {
0924: throw new NotImplementedException();
0925: }
0926:
0927: public Object getObject(String columnName) throws SQLException {
0928: return currentRow.getObject(getIndexByName(columnName));
0929: }
0930:
0931: public Object getObject(String columnName, Map<String, Class<?>> map)
0932: throws SQLException {
0933: throw new NotImplementedException();
0934: }
0935:
0936: public Ref getRef(int columnIndex) throws SQLException {
0937: throw new NotImplementedException();
0938: }
0939:
0940: public Ref getRef(String colName) throws SQLException {
0941: throw new NotImplementedException();
0942: }
0943:
0944: public int getRow() throws SQLException {
0945: // FIXME need more tests
0946: if (currentRow == null) {
0947: return 0;
0948: }
0949:
0950: return currentRowIndex;
0951: }
0952:
0953: public short getShort(int columnIndex) throws SQLException {
0954: throw new NotImplementedException();
0955: }
0956:
0957: public short getShort(String columnName) throws SQLException {
0958: throw new NotImplementedException();
0959: }
0960:
0961: public Statement getStatement() throws SQLException {
0962: throw new NotImplementedException();
0963: }
0964:
0965: // columnIndex: from 1 rather than 0
0966: public String getString(int columnIndex) throws SQLException {
0967: checkValidRow();
0968: Object value = currentRow.getObject(columnIndex);
0969: if (value == null) {
0970: return null;
0971: }
0972: return (String) value;
0973: }
0974:
0975: private boolean checkCursorValid() throws SQLException {
0976: if ((currentRowIndex <= 0) || (currentRowIndex > rows.size())) {
0977: // rowset.7=Not a valid cursor
0978: throw new SQLException(Messages.getString("rowset.7")); //$NON-NLS-1$
0979: }
0980: return false;
0981: }
0982:
0983: public String getString(String columnName) throws SQLException {
0984: return getString(getIndexByName(columnName));
0985: }
0986:
0987: public Time getTime(int columnIndex) throws SQLException {
0988: throw new NotImplementedException();
0989: }
0990:
0991: public Time getTime(int columnIndex, Calendar cal)
0992: throws SQLException {
0993: throw new NotImplementedException();
0994: }
0995:
0996: public Time getTime(String columnName) throws SQLException {
0997: throw new NotImplementedException();
0998: }
0999:
1000: public Time getTime(String columnName, Calendar cal)
1001: throws SQLException {
1002: throw new NotImplementedException();
1003: }
1004:
1005: public Timestamp getTimestamp(int columnIndex) throws SQLException {
1006: throw new NotImplementedException();
1007: }
1008:
1009: public Timestamp getTimestamp(int columnIndex, Calendar cal)
1010: throws SQLException {
1011: throw new NotImplementedException();
1012: }
1013:
1014: public Timestamp getTimestamp(String columnName)
1015: throws SQLException {
1016: throw new NotImplementedException();
1017: }
1018:
1019: public Timestamp getTimestamp(String columnName, Calendar cal)
1020: throws SQLException {
1021: throw new NotImplementedException();
1022: }
1023:
1024: public java.net.URL getURL(int columnIndex) throws SQLException {
1025: throw new NotImplementedException();
1026: }
1027:
1028: public java.net.URL getURL(String columnName) throws SQLException {
1029: throw new NotImplementedException();
1030: }
1031:
1032: public InputStream getUnicodeStream(int columnIndex)
1033: throws SQLException {
1034: throw new NotImplementedException();
1035: }
1036:
1037: public InputStream getUnicodeStream(String columnName)
1038: throws SQLException {
1039: throw new NotImplementedException();
1040: }
1041:
1042: public SQLWarning getWarnings() throws SQLException {
1043: throw new NotImplementedException();
1044: }
1045:
1046: public void insertRow() throws SQLException {
1047: checkValidRow();
1048: if (currentRow != insertRow) {
1049: // rowset.4=Not an insert row
1050: throw new SQLException(Messages.getString("rowset.4"));
1051: }
1052: insertRow.setInsert();
1053: rows.add(insertRow);
1054: insertRow = null;
1055: }
1056:
1057: public boolean isAfterLast() throws SQLException {
1058: if (rows == null || rows.size() == 0) {
1059: return false;
1060: }
1061:
1062: return currentRowIndex > rows.size();
1063: }
1064:
1065: public boolean isBeforeFirst() throws SQLException {
1066: if (rows == null || rows.size() == 0) {
1067: return false;
1068: }
1069:
1070: return currentRowIndex == 0;
1071: }
1072:
1073: public boolean isFirst() throws SQLException {
1074: return currentRowIndex == 1;
1075: }
1076:
1077: public boolean isLast() throws SQLException {
1078: if (rows == null || rows.size() == 0) {
1079: return false;
1080: }
1081:
1082: return currentRowIndex == rows.size();
1083: }
1084:
1085: public boolean last() throws SQLException {
1086: return doAbsolute(-1, true);
1087: }
1088:
1089: public void moveToCurrentRow() throws SQLException {
1090: if (rememberedCursorPosition != -1) {
1091: currentRowIndex = rememberedCursorPosition;
1092: if (currentRowIndex >= 1 && currentRowIndex <= size()) {
1093: currentRow = rows.get(currentRowIndex - 1);
1094: } else {
1095: currentRow = null;
1096: }
1097: rememberedCursorPosition = -1;
1098: }
1099: }
1100:
1101: public void moveToInsertRow() throws SQLException {
1102: insertRow = new CachedRow(new Object[columnCount]);
1103: currentRow = insertRow;
1104: rememberedCursorPosition = currentRowIndex;
1105: currentRowIndex = -1;
1106: }
1107:
1108: public boolean next() throws SQLException {
1109: /*
1110: * spec next() is identical with relative(1), but they can't:
1111: *
1112: * next() doesn't check TYPE_FORWARD_ONLY property, relative(1) does.
1113: */
1114: return doAbsolute(currentRowIndex + 1, false);
1115: }
1116:
1117: public boolean previous() throws SQLException {
1118: return doAbsolute(currentRowIndex - 1, true);
1119: }
1120:
1121: public void refreshRow() throws SQLException {
1122: throw new NotImplementedException();
1123: }
1124:
1125: public boolean relative(int moveRows) throws SQLException {
1126: if (currentRow == null) {
1127: // TODO add error message
1128: throw new SQLException();
1129: }
1130:
1131: int index = getRow() + moveRows;
1132: if (index <= 0) {
1133: beforeFirst();
1134: return false;
1135: }
1136:
1137: if (index > rows.size()) {
1138: afterLast();
1139: return false;
1140: }
1141:
1142: return doAbsolute(index, true);
1143: }
1144:
1145: public boolean rowDeleted() throws SQLException {
1146: checkValidRow();
1147: checkCursorValid();
1148: return currentRow.isDelete();
1149: }
1150:
1151: public boolean rowInserted() throws SQLException {
1152: if (currentRow == null || currentRow == insertRow) {
1153: // TODO add error message
1154: throw new SQLException();
1155: }
1156: return currentRow.isInsert();
1157: }
1158:
1159: public boolean rowUpdated() throws SQLException {
1160: if (!currentRow.isUpdate()) {
1161: return false;
1162: } else {
1163: boolean sign = false;
1164: for (int i = 0; i < meta.getColumnCount(); ++i) {
1165: sign = currentRow.getUpdateMask(i) | sign;
1166: }
1167: return sign;
1168: }
1169: }
1170:
1171: public void updateArray(int columnIndex, Array x)
1172: throws SQLException {
1173: throw new NotImplementedException();
1174: }
1175:
1176: public void updateArray(String columnName, Array x)
1177: throws SQLException {
1178: throw new NotImplementedException();
1179: }
1180:
1181: public void updateAsciiStream(int columnIndex, InputStream x,
1182: int length) throws SQLException {
1183: throw new NotImplementedException();
1184: }
1185:
1186: public void updateAsciiStream(String columnName, InputStream x,
1187: int length) throws SQLException {
1188: throw new NotImplementedException();
1189: }
1190:
1191: public void updateBigDecimal(int columnIndex, BigDecimal x)
1192: throws SQLException {
1193: currentRow.updateObject(columnIndex, x);
1194: }
1195:
1196: public void updateBigDecimal(String columnName, BigDecimal x)
1197: throws SQLException {
1198: updateBigDecimal(getIndexByName(columnName), x);
1199: }
1200:
1201: public void updateBinaryStream(int columnIndex, InputStream x,
1202: int length) throws SQLException {
1203: throw new NotImplementedException();
1204: }
1205:
1206: public void updateBinaryStream(String columnName, InputStream x,
1207: int length) throws SQLException {
1208: throw new NotImplementedException();
1209: }
1210:
1211: public void updateBlob(int columnIndex, Blob x) throws SQLException {
1212: throw new NotImplementedException();
1213: }
1214:
1215: public void updateBlob(String columnName, Blob x)
1216: throws SQLException {
1217: throw new NotImplementedException();
1218: }
1219:
1220: public void updateBoolean(int columnIndex, boolean x)
1221: throws SQLException {
1222: throw new NotImplementedException();
1223: }
1224:
1225: public void updateBoolean(String columnName, boolean x)
1226: throws SQLException {
1227: throw new NotImplementedException();
1228: }
1229:
1230: public void updateByte(int columnIndex, byte x) throws SQLException {
1231: throw new NotImplementedException();
1232: }
1233:
1234: public void updateByte(String columnName, byte x)
1235: throws SQLException {
1236: throw new NotImplementedException();
1237: }
1238:
1239: public void updateBytes(int columnIndex, byte[] x)
1240: throws SQLException {
1241: throw new NotImplementedException();
1242: }
1243:
1244: public void updateBytes(String columnName, byte[] x)
1245: throws SQLException {
1246: throw new NotImplementedException();
1247: }
1248:
1249: public void updateCharacterStream(int columnIndex, Reader x,
1250: int length) throws SQLException {
1251: throw new NotImplementedException();
1252: }
1253:
1254: public void updateCharacterStream(String columnName, Reader reader,
1255: int length) throws SQLException {
1256: throw new NotImplementedException();
1257: }
1258:
1259: public void updateClob(int columnIndex, Clob x) throws SQLException {
1260: throw new NotImplementedException();
1261: }
1262:
1263: public void updateClob(String columnName, Clob x)
1264: throws SQLException {
1265: throw new NotImplementedException();
1266: }
1267:
1268: public void updateDate(int columnIndex, Date x) throws SQLException {
1269: currentRow.updateObject(columnIndex, x);
1270: }
1271:
1272: public void updateDate(String columnName, Date x)
1273: throws SQLException {
1274: updateDate(getIndexByName(columnName), x);
1275: }
1276:
1277: public void updateDouble(int columnIndex, double x)
1278: throws SQLException {
1279: currentRow.updateObject(columnIndex, x);
1280: }
1281:
1282: public void updateDouble(String columnName, double x)
1283: throws SQLException {
1284: updateDouble(getIndexByName(columnName), x);
1285: }
1286:
1287: public void updateFloat(int columnIndex, float x)
1288: throws SQLException {
1289: currentRow.updateObject(columnIndex, x);
1290: }
1291:
1292: public void updateFloat(String columnName, float x)
1293: throws SQLException {
1294: updateFloat(getIndexByName(columnName), x);
1295: }
1296:
1297: public void updateInt(int columnIndex, int x) throws SQLException {
1298: currentRow.updateObject(columnIndex, x);
1299: }
1300:
1301: public void updateInt(String columnName, int x) throws SQLException {
1302: updateInt(getIndexByName(columnName), x);
1303: }
1304:
1305: public void updateLong(int columnIndex, long x) throws SQLException {
1306: currentRow.updateObject(columnIndex, x);
1307: }
1308:
1309: public void updateLong(String columnName, long x)
1310: throws SQLException {
1311: updateLong(getIndexByName(columnName), x);
1312: }
1313:
1314: public void updateNull(int columnIndex) throws SQLException {
1315: throw new NotImplementedException();
1316: }
1317:
1318: public void updateNull(String columnName) throws SQLException {
1319: throw new NotImplementedException();
1320: }
1321:
1322: public void updateObject(int columnIndex, Object x)
1323: throws SQLException {
1324: throw new NotImplementedException();
1325: }
1326:
1327: public void updateObject(int columnIndex, Object x, int scale)
1328: throws SQLException {
1329: throw new NotImplementedException();
1330: }
1331:
1332: public void updateObject(String columnName, Object x)
1333: throws SQLException {
1334: throw new NotImplementedException();
1335: }
1336:
1337: public void updateObject(String columnName, Object x, int scale)
1338: throws SQLException {
1339: throw new NotImplementedException();
1340: }
1341:
1342: public void updateRef(int columnIndex, Ref x) throws SQLException {
1343: throw new NotImplementedException();
1344: }
1345:
1346: public void updateRef(String columnName, Ref x) throws SQLException {
1347: throw new NotImplementedException();
1348: }
1349:
1350: public void updateRow() throws SQLException {
1351: if ((currentRow == insertRow)
1352: || (getConcurrency() == (ResultSet.CONCUR_READ_ONLY))) {
1353: // TODO add error messages
1354: throw new SQLException();
1355: }
1356: currentRow.setUpdate();
1357: notifyRowChanged();
1358: }
1359:
1360: public void updateShort(int columnIndex, short x)
1361: throws SQLException {
1362: throw new NotImplementedException();
1363: }
1364:
1365: public void updateShort(String columnName, short x)
1366: throws SQLException {
1367: throw new NotImplementedException();
1368: }
1369:
1370: public void updateString(int columnIndex, String x)
1371: throws SQLException {
1372: currentRow.updateObject(columnIndex, x);
1373: }
1374:
1375: public void updateString(String columnName, String x)
1376: throws SQLException {
1377: updateString(getIndexByName(columnName), x);
1378: }
1379:
1380: public void updateTime(int columnIndex, Time x) throws SQLException {
1381: currentRow.updateObject(columnIndex, x);
1382: }
1383:
1384: public void updateTime(String columnName, Time x)
1385: throws SQLException {
1386: updateTime(getIndexByName(columnName), x);
1387: }
1388:
1389: public void updateTimestamp(int columnIndex, Timestamp x)
1390: throws SQLException {
1391: currentRow.updateObject(columnIndex, x);
1392: }
1393:
1394: public void updateTimestamp(String columnName, Timestamp x)
1395: throws SQLException {
1396: updateTimestamp(getIndexByName(columnName), x);
1397: }
1398:
1399: public boolean wasNull() throws SQLException {
1400: // return (currentColumn instanceof Types(Types.NULL));
1401: throw new NotImplementedException();
1402: }
1403:
1404: public void execute() throws SQLException {
1405: execute(getConnection());
1406: }
1407:
1408: public Connection getConnection() throws SQLException {
1409: return DriverManager.getConnection(getUrl());
1410: }
1411:
1412: CachedRow getCurrentRow() {
1413: return currentRow;
1414: }
1415:
1416: @Override
1417: public void setCommand(String cmd) throws SQLException {
1418: initParams();
1419: super.setCommand(cmd);
1420: }
1421:
1422: }
|