001: package com.quadcap.sql;
002:
003: /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
004: *
005: * This software is distributed under the Quadcap Free Software License.
006: * This software may be used or modified for any purpose, personal or
007: * commercial. Open Source redistributions are permitted. Commercial
008: * redistribution of larger works derived from, or works which bundle
009: * this software requires a "Commercial Redistribution License"; see
010: * http://www.quadcap.com/purchase.
011: *
012: * Redistributions qualify as "Open Source" under one of the following terms:
013: *
014: * Redistributions are made at no charge beyond the reasonable cost of
015: * materials and delivery.
016: *
017: * Redistributions are accompanied by a copy of the Source Code or by an
018: * irrevocable offer to provide a copy of the Source Code for up to three
019: * years at the cost of materials and delivery. Such redistributions
020: * must allow further use, modification, and redistribution of the Source
021: * Code under substantially the same terms as this license.
022: *
023: * Redistributions of source code must retain the copyright notices as they
024: * appear in each source code file, these license terms, and the
025: * disclaimer/limitation of liability set forth as paragraph 6 below.
026: *
027: * Redistributions in binary form must reproduce this Copyright Notice,
028: * these license terms, and the disclaimer/limitation of liability set
029: * forth as paragraph 6 below, in the documentation and/or other materials
030: * provided with the distribution.
031: *
032: * The Software is provided on an "AS IS" basis. No warranty is
033: * provided that the Software is free of defects, or fit for a
034: * particular purpose.
035: *
036: * Limitation of Liability. Quadcap Software shall not be liable
037: * for any damages suffered by the Licensee or any third party resulting
038: * from use of the Software.
039: */
040:
041: import java.io.Externalizable;
042: import java.io.IOException;
043: import java.io.ObjectInput;
044: import java.io.ObjectOutput;
045:
046: import java.sql.SQLException;
047:
048: import com.quadcap.sql.io.ObjectInputStream;
049: import com.quadcap.sql.io.ObjectOutputStream;
050:
051: import com.quadcap.sql.file.SubPageManager;
052: import com.quadcap.sql.index.BCursor;
053:
054: import com.quadcap.util.Debug;
055:
056: /**
057: * Cursor that implements the <b>DISTINCT</b> modifier by creating
058: * temporary table, where the entire row is used as the index key.
059: *
060: * @author Stan Bailes
061: */
062: public abstract class BC_Cursor extends CursorImpl {
063: protected BCursor bc = null;
064: protected LazyRow row = null;
065: protected boolean rowValid = false;
066: protected long rowId = 0;
067:
068: /**
069: * Constructor on session and cursor
070: */
071: public BC_Cursor(Session session, String name, Cursor outer)
072: throws SQLException {
073: super (session, name, outer);
074: }
075:
076: /**
077: * Cursor.getRow(): return the current table row, fetching it if necessary
078: * based on the rowId
079: */
080: public Row getRow() throws SQLException {
081: Row ret = null;
082: if (rowId != 0) {
083: if (!rowValid) {
084: try {
085: fetchCurrentRow();
086: } catch (IOException ex) {
087: throw DbException.wrapThrowable(ex);
088: }
089: }
090: if (rowValid) {
091: ret = row;
092: }
093: }
094: return row;
095: }
096:
097: /**
098: * Make the row too, while you're at it...
099: */
100: public abstract void checkCursor() throws IOException, SQLException;
101:
102: public abstract long getCurrentRowId() throws IOException,
103: SQLException;
104:
105: public abstract void fetchCurrentRow() throws IOException,
106: SQLException;
107:
108: public boolean isWritable(int column) {
109: return false;
110: }
111:
112: public boolean absolute(int x) throws SQLException {
113: try {
114: rowValid = false;
115: rowId = 0;
116: checkCursor();
117: boolean ret = bc.absolute(x);
118: if (ret) {
119: rowId = getCurrentRowId();
120: }
121: return ret;
122: } catch (IOException e) {
123: throw DbException.wrapThrowable(e);
124: }
125: }
126:
127: public void beforeFirst() throws SQLException {
128: try {
129: rowValid = false;
130: rowId = 0;
131: checkCursor();
132: bc.beforeFirst();
133: } catch (IOException e) {
134: throw DbException.wrapThrowable(e);
135: }
136: }
137:
138: public void afterLast() throws SQLException {
139: try {
140: rowValid = false;
141: rowId = 0;
142: checkCursor();
143: bc.afterLast();
144: } catch (IOException e) {
145: throw DbException.wrapThrowable(e);
146: }
147: }
148:
149: public boolean next() throws SQLException {
150: try {
151: rowValid = false;
152: rowId = 0;
153: checkCursor();
154: boolean ret = bc.next();
155: if (ret) {
156: rowId = getCurrentRowId();
157: }
158: return ret;
159: } catch (IOException e) {
160: throw DbException.wrapThrowable(e);
161: }
162: }
163:
164: public boolean prev() throws SQLException {
165: try {
166: rowValid = false;
167: rowId = 0;
168: checkCursor();
169: boolean ret = bc.prev();
170: if (ret)
171: rowId = getCurrentRowId();
172: return ret;
173: } catch (IOException e) {
174: throw DbException.wrapThrowable(e);
175: }
176: }
177:
178: /**
179: * On close, we release the resources.
180: */
181: public void close() throws SQLException {
182: try {
183: if (bc != null)
184: bc.release();
185: } finally {
186: bc = null;
187: row = null;
188: }
189: }
190:
191: /**
192: * Return the row id
193: */
194: public long getRowId() {
195: return rowId;
196: }
197:
198: /**
199: * Return the size of the index backing this cursor.
200: */
201: public long size() throws SQLException {
202: try {
203: return bc.size();
204: } catch (IOException e) {
205: throw DbException.wrapThrowable(e);
206: }
207: }
208:
209: public void updateRow(Row row) throws SQLException {
210: throw new SQLException("Cursor not updateable");
211: }
212:
213: public void deleteRow() throws SQLException {
214: throw new SQLException("Cursor not updateable");
215: }
216: }
|