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.util.Collections;
047: import java.util.Comparator;
048: import java.util.Vector;
049:
050: import java.sql.SQLException;
051:
052: import com.quadcap.sql.types.Op;
053: import com.quadcap.sql.types.Value;
054: import com.quadcap.sql.types.ValueException;
055:
056: import com.quadcap.util.Debug;
057:
058: /**
059: * Cursor implementation of <b>VALUES</b> clause. Contains either a row
060: * or a Vector of rows.
061: *
062: * @author Stan Bailes
063: */
064: public class StaticCursor extends CursorImpl implements Externalizable {
065: Tuple tuple = null;
066: Vector v;
067: Row currentRow = null;
068: int pos = 0;
069:
070: /**
071: * Constructor for a static cursor from a tuple and single row
072: */
073: public StaticCursor(Session session, Tuple tuple, Row row) {
074: super (session, "");
075: this .tuple = tuple;
076: this .v = new Vector();
077: v.addElement(row);
078: }
079:
080: /**
081: * Constructor for a static cursor from a vector of rows.
082: */
083: public StaticCursor(Session session, Vector v) {
084: super (session, "");
085: this .v = v;
086: }
087:
088: /**
089: * Add a row to the cursor's row set.
090: */
091: public void addRow(Row row) {
092: v.addElement(row);
093: }
094:
095: /**
096: * Return the current row
097: */
098: public Row getRow() {
099: return currentRow;
100: }
101:
102: /**
103: * Static cursors aren't updateable.
104: */
105: public void updateRow(Row row) throws SQLException {
106: throw new SQLException("Not implemented for static cursor",
107: "0A000");
108: }
109:
110: /**
111: * Static cursors aren't updateable.
112: */
113: public void deleteRow() throws SQLException {
114: throw new SQLException("Not implemented for static cursor",
115: "0A000");
116: }
117:
118: /**
119: * Return the specified column.
120: *
121: * Static cursors may or may not have tuple information. If they
122: * do, use the tuple information directly, otherwise default to the
123: * superclass (TupleImpl) implementation of getColumn.
124: */
125: public Column getColumn(int col) throws SQLException {
126: if (tuple == null) {
127: return super .getColumn(col);
128: }
129: return tuple.getColumn(col);
130: }
131:
132: /**
133: * Return the specified column.
134: *
135: * Static cursors may or may not have tuple information. If they
136: * do, use the tuple information directly, otherwise default to the
137: * superclass (TupleImpl) implementation of getColumn.
138: */
139: public Column getColumn(String columnName) throws SQLException {
140: if (tuple == null) {
141: return super .getColumn(columnName);
142: }
143: return tuple.getColumn(columnName);
144: }
145:
146: /**
147: * Get the value for the specified column
148: */
149: public Value get(String columnName) throws SQLException {
150: Column col = getColumn(columnName);
151: if (col != null) {
152: return currentRow.item(col.getColumn());
153: }
154: return null;
155: }
156:
157: /**
158: * Put a new value into the current row for the specified column
159: * (Who calls this? We're not supposed to be writable!!!)
160: */
161: public void put(String columnName, Value v) throws SQLException {
162: Column col = getColumn(columnName);
163: if (col != null) {
164: currentRow.set(col.getColumn(), v);
165: }
166: }
167:
168: /**
169: * Return the column count.
170: */
171: public int getColumnCount() throws SQLException {
172: if (tuple != null)
173: return tuple.getColumnCount();
174: int ret = super .getColumnCount();
175: if (ret > 0)
176: return ret;
177: if (v.size() > 0) {
178: Row row = (Row) v.elementAt(0);
179: return row.size();
180: }
181: throw new SQLException("no columns", "Q0017");
182: }
183:
184: /**
185: * Static cursors don't allow column update
186: */
187: public boolean isWritable(int column) {
188: return false;
189: }
190:
191: /**
192: * Return the number of rows in this cursor.
193: */
194: public long size() throws SQLException {
195: return v.size();
196: }
197:
198: /**
199: * Position the cursor to the specified absolute row. The first row
200: * is row '1', and the last row is '-1', as in JDBC.
201: */
202: public boolean absolute(int row) throws SQLException {
203: currentRow = null;
204: if (row == 0) {
205: throw new SQLException(
206: "Attempt to position cursor on row zero", "42000");
207: }
208: if (row < 0) {
209: row += v.size();
210: }
211: if (row <= 0 || row > v.size())
212: return false;
213: currentRow = (Row) v.elementAt(row - 1);
214: return true;
215: }
216:
217: /**
218: * Position the cursor before the first row.
219: */
220: public void beforeFirst() throws SQLException {
221: pos = 0;
222: }
223:
224: /**
225: * Position the cursor after the last row.
226: */
227: public void afterLast() throws SQLException {
228: pos = v.size();
229: }
230:
231: /**
232: * Move the cursor to the next row and return true if the cursor is
233: * positioned on a valid row.
234: */
235: public boolean next() {
236: currentRow = null;
237: if (pos < v.size()) {
238: currentRow = (Row) v.elementAt(pos++);
239: }
240: return currentRow != null;
241: }
242:
243: /**
244: * Move the cursor to the previous row and return true if the cursor is
245: * positioned on a valid row.
246: */
247: public boolean prev() {
248: currentRow = null;
249: if (pos > 0 && pos <= v.size()) {
250: currentRow = (Row) v.elementAt(--pos);
251: }
252: return currentRow != null;
253: }
254:
255: /**
256: * Read me from a stream
257: */
258: public void readExternal(ObjectInput in) throws IOException,
259: ClassNotFoundException {
260: this .pos = in.readInt();
261: this .v = (Vector) in.readObject();
262: }
263:
264: /**
265: * Write me to a stream
266: */
267: public void writeExternal(ObjectOutput out) throws IOException {
268: out.writeInt(pos);
269: out.writeObject(v);
270: }
271:
272: /**
273: * Close.
274: */
275: public void close() {
276: tuple = null;
277: currentRow = null;
278: v = null;
279: }
280:
281: public int[] getSortColumns() {
282: return new int[0];
283: }
284:
285: public Comparator getComparator() {
286: return new Comparator() {
287: public int compare(Object o1, Object o2) {
288: try {
289: Row r1 = (Row) o1;
290: Row r2 = (Row) o2;
291: int[] keys = getSortColumns();
292: for (int i = 0; i < keys.length; i++) {
293: int col = keys[i];
294: Value v1 = r1.item(col);
295: Value v2 = r2.item(col);
296: if (Value.boolOp(Op.LT, v1, v2))
297: return -1;
298: if (Value.boolOp(Op.GT, v1, v2))
299: return 1;
300: }
301: } catch (ValueException e) {
302: Debug.print(e);
303: throw new DbRuntimeException(e);
304: } catch (SQLException e) {
305: Debug.print(e);
306: throw new DbRuntimeException(e);
307: } catch (Throwable e) {
308: Debug.print(e);
309: throw new DbRuntimeException(e);
310: }
311: return 0;
312: }
313: };
314: }
315:
316: public void sort() throws ValueException, SQLException {
317: try {
318: Collections.sort(v, getComparator());
319: } catch (DbRuntimeException e) {
320: Throwable ex = e.getException();
321: if (ex instanceof ValueException) {
322: throw (ValueException) ex;
323: } else if (ex instanceof SQLException) {
324: throw (SQLException) ex;
325: } else {
326: throw e;
327: }
328: }
329: }
330:
331: public void updateRow(int pos, Row row) {
332: v.setElementAt(row, pos);
333: }
334:
335: public void reset() {
336: pos = 0;
337: }
338: }
|