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.Enumeration;
047: import java.util.Hashtable;
048: import java.util.Vector;
049:
050: import java.sql.SQLException;
051:
052: import com.quadcap.sql.types.Type;
053: import com.quadcap.sql.types.TypeAny;
054: import com.quadcap.sql.types.Value;
055:
056: import com.quadcap.util.Debug;
057:
058: /**
059: * This cursor performs the name-mapping function associated with the
060: * <code>SELECT</code> clause.
061: *
062: * @author Stan Bailes
063: */
064: public class ItemsCursor extends CursorImpl {
065: Cursor cursor;
066: ItemsRow currentRow = null;
067: int[] map = null;
068: Vector items;
069:
070: public ItemsCursor(Session session, Cursor cursor, Vector gitems)
071: throws SQLException {
072: super (session, cursor.getName());
073: this .session = session;
074: this .cursor = cursor;
075: this .items = expandWildCard(session, cursor, gitems);
076: this .map = new int[items.size()];
077: for (int i = 0; i < items.size(); i++) {
078: SelectItem item = (SelectItem) items.elementAt(i);
079: Expression e = item.getExpression();
080: if (e instanceof NameExpression) {
081: String name = ((NameExpression) e).getName();
082: String asName = item.getAsName();
083: if (asName == null)
084: asName = name;
085: Column col = cursor.getColumn(name);
086: if (col == null) {
087: //#ifdef DEBUG
088: Debug.println(0, cursor.toString());
089: //#endif
090: throw new SQLException("Bad column name: " + name,
091: "42000");
092: }
093: addColumn(new Column(asName, col));
094: map[i] = col.getColumn();
095: } else {
096: String asName = item.getAsName();
097: if (asName == null) {
098: asName = "Column" + (i + 1);
099: }
100: addColumn(new Column(asName, e.getType(session, cursor)));
101: map[i] = -1;
102: }
103: }
104: }
105:
106: final Vector expandWildCard(Session session, Cursor cursor,
107: Vector items) throws SQLException {
108: Vector nitems = new Vector();
109: for (int i = 0; i < items.size(); i++) {
110: SelectItem item = (SelectItem) items.elementAt(i);
111: Expression e = item.getExpression();
112: String name = "Column" + (i + 1);
113: if (e instanceof NameExpression) {
114: name = ((NameExpression) e).getName();
115: if (name.endsWith(".*")) {
116: String rname = name.substring(0, name.length() - 2);
117: String qname = session.getConnection().resolveName(
118: rname)
119: + ".";
120: rname = rname + ".";
121: boolean found = false;
122: for (int j = 1; j <= cursor.getColumnCount(); j++) {
123: Column col = cursor.getColumn(j);
124: if (col.isJoinColumn())
125: continue;
126: String sname = col.getShortName();
127: String cname = col.getName();
128: if (sname.startsWith(rname)
129: || sname.startsWith(qname)) {
130: found = true;
131: nitems.addElement(new SelectItem(
132: new NameExpression(sname)));
133: } else if (cname.startsWith(qname)
134: || cname.startsWith(rname)) {
135: found = true;
136: nitems.addElement(new SelectItem(
137: new NameExpression(cname)));
138: }
139: }
140: if (!found) {
141: throw new SQLException("Bad column name: "
142: + name, "42000");
143: }
144: } else {
145: nitems.addElement(item);
146: }
147: } else {
148: nitems.addElement(item);
149: }
150: }
151: return nitems;
152: }
153:
154: public Row getEmptyAggregate() throws SQLException {
155: return new ItemsRow(session, items, null, null, map);
156: }
157:
158: public void updateRow(Row row) throws SQLException {
159: for (int i = 1; i <= map.length; i++) {
160: Value v = row.item(i);
161: currentRow.set(i, v);
162: }
163: cursor.updateRow(currentRow.getBaseRow());
164: }
165:
166: public void insertRow(Row row) throws SQLException {
167: if (currentRow == null) {
168: makeCurrentRow();
169: }
170: for (int i = 1; i <= map.length; i++) {
171: Value v = row.item(i);
172: currentRow.set(i, v);
173: }
174: cursor.insertRow(currentRow.getBaseRow());
175: }
176:
177: public void deleteRow() throws SQLException {
178: cursor.deleteRow();
179: }
180:
181: public boolean isWritable(int column) throws SQLException {
182: return cursor.isWritable(map[column - 1]);
183: }
184:
185: public void beforeFirst() throws SQLException {
186: cursor.beforeFirst();
187: }
188:
189: public void afterLast() throws SQLException {
190: cursor.afterLast();
191: }
192:
193: final void makeFirstRow() throws SQLException {
194: Row r = cursor.getRow();
195: currentRow = new ItemsRow(session, items, cursor, r, map);
196: for (int i = 0; i < map.length; i++) {
197: if (map[i] == -1) {
198: Column col = getColumn(i + 1);
199: Value v = currentRow.item(i + 1);
200: col.setType(v.getType());
201: }
202: }
203: }
204:
205: final void makeCurrentRow() throws SQLException {
206: currentRow = new ItemsRow(session, items, cursor, null, map);
207: }
208:
209: public boolean next() throws SQLException {
210: return cursor.next();
211: }
212:
213: public Row getRow() throws SQLException {
214: if (currentRow == null) {
215: makeFirstRow();
216: } else {
217: currentRow.nextRow(cursor.getRow());
218: }
219: return currentRow;
220: }
221:
222: public void setOuterCursor(Cursor c) {
223: super .setOuterCursor(c);
224: if (cursor != null)
225: cursor.setOuterCursor(c);
226: }
227:
228: public void close() throws SQLException {
229: cursor.close();
230: }
231:
232: public long size() throws SQLException {
233: return cursor.size();
234: }
235:
236: public Cursor getBaseCursor() {
237: return cursor;
238: }
239:
240: //#ifdef DEBUG
241: public String toString() {
242: return super .toString() + " : (cursor = " + cursor + ")";
243: }
244: //#endif
245:
246: }
|