Quadcap Embeddable Database

com/quadcap/sql/StaticCursor.java

Go to the documentation of this file.
00001 package com.quadcap.sql; 00002 00003 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved. 00004 * 00005 * This software is distributed under the Quadcap Free Software License. 00006 * This software may be used or modified for any purpose, personal or 00007 * commercial. Open Source redistributions are permitted. Commercial 00008 * redistribution of larger works derived from, or works which bundle 00009 * this software requires a "Commercial Redistribution License"; see 00010 * http://www.quadcap.com/purchase. 00011 * 00012 * Redistributions qualify as "Open Source" under one of the following terms: 00013 * 00014 * Redistributions are made at no charge beyond the reasonable cost of 00015 * materials and delivery. 00016 * 00017 * Redistributions are accompanied by a copy of the Source Code or by an 00018 * irrevocable offer to provide a copy of the Source Code for up to three 00019 * years at the cost of materials and delivery. Such redistributions 00020 * must allow further use, modification, and redistribution of the Source 00021 * Code under substantially the same terms as this license. 00022 * 00023 * Redistributions of source code must retain the copyright notices as they 00024 * appear in each source code file, these license terms, and the 00025 * disclaimer/limitation of liability set forth as paragraph 6 below. 00026 * 00027 * Redistributions in binary form must reproduce this Copyright Notice, 00028 * these license terms, and the disclaimer/limitation of liability set 00029 * forth as paragraph 6 below, in the documentation and/or other materials 00030 * provided with the distribution. 00031 * 00032 * The Software is provided on an "AS IS" basis. No warranty is 00033 * provided that the Software is free of defects, or fit for a 00034 * particular purpose. 00035 * 00036 * Limitation of Liability. Quadcap Software shall not be liable 00037 * for any damages suffered by the Licensee or any third party resulting 00038 * from use of the Software. 00039 */ 00040 00041 import java.io.Externalizable; 00042 import java.io.IOException; 00043 import java.io.ObjectInput; 00044 import java.io.ObjectOutput; 00045 00046 import java.util.Collections; 00047 import java.util.Comparator; 00048 import java.util.Vector; 00049 00050 import java.sql.SQLException; 00051 00052 import com.quadcap.sql.types.Op; 00053 import com.quadcap.sql.types.Value; 00054 import com.quadcap.sql.types.ValueException; 00055 00056 import com.quadcap.util.Debug; 00057 00058 /** 00059 * Cursor implementation of <b>VALUES</b> clause. Contains either a row 00060 * or a Vector of rows. 00061 * 00062 * @author Stan Bailes 00063 */ 00064 public class StaticCursor extends CursorImpl implements Externalizable { 00065 Tuple tuple = null; 00066 Vector v; 00067 Row currentRow = null; 00068 int pos = 0; 00069 00070 /** 00071 * Constructor for a static cursor from a tuple and single row 00072 */ 00073 public StaticCursor(Session session, Tuple tuple, Row row) { 00074 super(session, ""); 00075 this.tuple = tuple; 00076 this.v = new Vector(); 00077 v.addElement(row); 00078 } 00079 00080 /** 00081 * Constructor for a static cursor from a vector of rows. 00082 */ 00083 public StaticCursor(Session session, Vector v) { 00084 super(session, ""); 00085 this.v = v; 00086 } 00087 00088 /** 00089 * Add a row to the cursor's row set. 00090 */ 00091 public void addRow(Row row) { 00092 v.addElement(row); 00093 } 00094 00095 /** 00096 * Return the current row 00097 */ 00098 public Row getRow() { 00099 return currentRow; 00100 } 00101 00102 /** 00103 * Static cursors aren't updateable. 00104 */ 00105 public void updateRow(Row row) throws SQLException { 00106 throw new SQLException("Not implemented for static cursor", "0A000"); 00107 } 00108 00109 /** 00110 * Static cursors aren't updateable. 00111 */ 00112 public void deleteRow() throws SQLException { 00113 throw new SQLException("Not implemented for static cursor", "0A000"); 00114 } 00115 00116 /** 00117 * Return the specified column. 00118 * 00119 * Static cursors may or may not have tuple information. If they 00120 * do, use the tuple information directly, otherwise default to the 00121 * superclass (TupleImpl) implementation of getColumn. 00122 */ 00123 public Column getColumn(int col) throws SQLException { 00124 if (tuple == null) { 00125 return super.getColumn(col); 00126 } 00127 return tuple.getColumn(col); 00128 } 00129 00130 /** 00131 * Return the specified column. 00132 * 00133 * Static cursors may or may not have tuple information. If they 00134 * do, use the tuple information directly, otherwise default to the 00135 * superclass (TupleImpl) implementation of getColumn. 00136 */ 00137 public Column getColumn(String columnName) throws SQLException { 00138 if (tuple == null) { 00139 return super.getColumn(columnName); 00140 } 00141 return tuple.getColumn(columnName); 00142 } 00143 00144 /** 00145 * Get the value for the specified column 00146 */ 00147 public Value get(String columnName) throws SQLException { 00148 Column col = getColumn(columnName); 00149 if (col != null) { 00150 return currentRow.item(col.getColumn()); 00151 } 00152 return null; 00153 } 00154 00155 /** 00156 * Put a new value into the current row for the specified column 00157 * (Who calls this? We're not supposed to be writable!!!) 00158 */ 00159 public void put(String columnName, Value v) throws SQLException { 00160 Column col = getColumn(columnName); 00161 if (col != null) { 00162 currentRow.set(col.getColumn(), v); 00163 } 00164 } 00165 00166 /** 00167 * Return the column count. 00168 */ 00169 public int getColumnCount() throws SQLException { 00170 if (tuple != null) return tuple.getColumnCount(); 00171 int ret = super.getColumnCount(); 00172 if (ret > 0) return ret; 00173 if (v.size() > 0) { 00174 Row row = (Row)v.elementAt(0); 00175 return row.size(); 00176 } 00177 throw new SQLException("no columns", "Q0017"); 00178 } 00179 00180 /** 00181 * Static cursors don't allow column update 00182 */ 00183 public boolean isWritable(int column) { return false; } 00184 00185 /** 00186 * Return the number of rows in this cursor. 00187 */ 00188 public long size() throws SQLException { return v.size(); } 00189 00190 /** 00191 * Position the cursor to the specified absolute row. The first row 00192 * is row '1', and the last row is '-1', as in JDBC. 00193 */ 00194 public boolean absolute(int row) throws SQLException { 00195 currentRow = null; 00196 if (row == 0) { 00197 throw new SQLException("Attempt to position cursor on row zero", 00198 "42000"); 00199 } 00200 if (row < 0) { 00201 row += v.size(); 00202 } 00203 if (row <= 0 || row > v.size()) return false; 00204 currentRow = (Row)v.elementAt(row-1); 00205 return true; 00206 } 00207 00208 /** 00209 * Position the cursor before the first row. 00210 */ 00211 public void beforeFirst() throws SQLException { 00212 pos = 0; 00213 } 00214 00215 /** 00216 * Position the cursor after the last row. 00217 */ 00218 public void afterLast() throws SQLException { 00219 pos = v.size(); 00220 } 00221 00222 /** 00223 * Move the cursor to the next row and return true if the cursor is 00224 * positioned on a valid row. 00225 */ 00226 public boolean next() { 00227 currentRow = null; 00228 if (pos < v.size()) { 00229 currentRow = (Row)v.elementAt(pos++); 00230 } 00231 return currentRow != null; 00232 } 00233 00234 /** 00235 * Move the cursor to the previous row and return true if the cursor is 00236 * positioned on a valid row. 00237 */ 00238 public boolean prev() { 00239 currentRow = null; 00240 if (pos > 0 && pos <= v.size()) { 00241 currentRow = (Row)v.elementAt(--pos); 00242 } 00243 return currentRow != null; 00244 } 00245 00246 /** 00247 * Read me from a stream 00248 */ 00249 public void readExternal(ObjectInput in) 00250 throws IOException, ClassNotFoundException 00251 { 00252 this.pos = in.readInt(); 00253 this.v = (Vector)in.readObject(); 00254 } 00255 00256 /** 00257 * Write me to a stream 00258 */ 00259 public void writeExternal(ObjectOutput out) throws IOException { 00260 out.writeInt(pos); 00261 out.writeObject(v); 00262 } 00263 00264 /** 00265 * Close. 00266 */ 00267 public void close() { 00268 tuple = null; 00269 currentRow = null; 00270 v = null; 00271 } 00272 00273 public int[] getSortColumns() { 00274 return new int[0]; 00275 } 00276 00277 public Comparator getComparator() { 00278 return new Comparator() { 00279 public int compare(Object o1, Object o2) { 00280 try { 00281 Row r1 = (Row)o1; 00282 Row r2 = (Row)o2; 00283 int[] keys = getSortColumns(); 00284 for (int i = 0; i < keys.length; i++) { 00285 int col = keys[i]; 00286 Value v1 = r1.item(col); 00287 Value v2 = r2.item(col); 00288 if (Value.boolOp(Op.LT, v1, v2)) return -1; 00289 if (Value.boolOp(Op.GT, v1, v2)) return 1; 00290 } 00291 } catch (ValueException e) { 00292 Debug.print(e); 00293 throw new DbRuntimeException(e); 00294 } catch (SQLException e) { 00295 Debug.print(e); 00296 throw new DbRuntimeException(e); 00297 } catch (Throwable e) { 00298 Debug.print(e); 00299 throw new DbRuntimeException(e); 00300 } 00301 return 0; 00302 } 00303 }; 00304 } 00305 00306 public void sort() throws ValueException, SQLException { 00307 try { 00308 Collections.sort(v, getComparator()); 00309 } catch (DbRuntimeException e) { 00310 Throwable ex = e.getException(); 00311 if (ex instanceof ValueException) { 00312 throw (ValueException)ex; 00313 } else if (ex instanceof SQLException) { 00314 throw (SQLException)ex; 00315 } else { 00316 throw e; 00317 } 00318 } 00319 } 00320 00321 public void updateRow(int pos, Row row) { 00322 v.setElementAt(row, pos); 00323 } 00324 00325 public void reset() { 00326 pos = 0; 00327 } 00328 }