001: /* Copyright (c) 2001-2005, The HSQL Development Group
002: * All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * Redistributions of source code must retain the above copyright notice, this
008: * list of conditions and the following disclaimer.
009: *
010: * Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * Neither the name of the HSQL Development Group nor the names of its
015: * contributors may be used to endorse or promote products derived from this
016: * software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
022: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
026: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package org.hsqldb.rowio;
032:
033: import java.io.IOException;
034: import java.math.BigDecimal;
035: import java.sql.Date;
036: import java.sql.Time;
037: import java.sql.Timestamp;
038:
039: import org.hsqldb.HsqlException;
040: import org.hsqldb.Trace;
041: import org.hsqldb.Types;
042: import org.hsqldb.lib.HsqlByteArrayInputStream;
043: import org.hsqldb.types.Binary;
044:
045: /**
046: * Base class for reading the data for a database row in different formats.
047: * Defines the methods that are independent of storage format and declares
048: * the format-dependent methods that subclasses should define.
049: *
050: * @author sqlbob@users (RMP)
051: * @author fredt@users
052: * @version 1.7.2
053: * @since 1.7.0
054: */
055: public abstract class RowInputBase extends HsqlByteArrayInputStream {
056:
057: static final int NO_POS = -1;
058:
059: // fredt - initialisation may be unnecessary as it's done in resetRow()
060: protected int filePos = NO_POS;
061: protected int size;
062:
063: public RowInputBase() {
064: this (new byte[4]);
065: }
066:
067: /**
068: * Constructor takes a complete row
069: */
070: public RowInputBase(byte[] buf) {
071:
072: super (buf);
073:
074: size = buf.length;
075: }
076:
077: public int getPos() {
078:
079: if (filePos == NO_POS) {
080:
081: // Trace.printSystemOut(Trace.DatabaseRowInput_getPos);
082: }
083:
084: return (filePos);
085: }
086:
087: public int getSize() {
088: return size;
089: }
090:
091: // fredt@users - comment - methods used for node and type data
092: public abstract int readIntData() throws IOException;
093:
094: public abstract long readLongData() throws IOException;
095:
096: public abstract int readType() throws IOException;
097:
098: public abstract String readString() throws IOException;
099:
100: // fredt@users - comment - methods used for SQL types
101: protected abstract boolean checkNull() throws IOException;
102:
103: protected abstract String readChar(int type) throws IOException,
104: HsqlException;
105:
106: protected abstract Integer readSmallint() throws IOException,
107: HsqlException;
108:
109: protected abstract Integer readInteger() throws IOException,
110: HsqlException;
111:
112: protected abstract Long readBigint() throws IOException,
113: HsqlException;
114:
115: protected abstract Double readReal(int type) throws IOException,
116: HsqlException;
117:
118: protected abstract BigDecimal readDecimal() throws IOException,
119: HsqlException;
120:
121: protected abstract Boolean readBit() throws IOException,
122: HsqlException;
123:
124: protected abstract Time readTime() throws IOException,
125: HsqlException;
126:
127: protected abstract Date readDate() throws IOException,
128: HsqlException;
129:
130: protected abstract Timestamp readTimestamp() throws IOException,
131: HsqlException;
132:
133: protected abstract Object readOther() throws IOException,
134: HsqlException;
135:
136: protected abstract Binary readBinary(int type) throws IOException,
137: HsqlException;
138:
139: /**
140: * reads row data from a stream using the JDBC types in colTypes
141: *
142: * @param colTypes
143: * @return
144: * @throws IOException
145: * @throws HsqlException
146: */
147: public Object[] readData(int[] colTypes) throws IOException,
148: HsqlException {
149:
150: int l = colTypes.length;
151: Object[] data = new Object[l];
152: Object o;
153: int type;
154:
155: for (int i = 0; i < l; i++) {
156: if (checkNull()) {
157: continue;
158: }
159:
160: o = null;
161: type = colTypes[i];
162:
163: switch (type) {
164:
165: case Types.NULL:
166: case Types.CHAR:
167: case Types.VARCHAR:
168: case Types.VARCHAR_IGNORECASE:
169: case Types.LONGVARCHAR:
170: o = readChar(type);
171: break;
172:
173: case Types.TINYINT:
174: case Types.SMALLINT:
175: o = readSmallint();
176: break;
177:
178: case Types.INTEGER:
179: o = readInteger();
180: break;
181:
182: case Types.BIGINT:
183: o = readBigint();
184: break;
185:
186: //fredt although REAL is now Double, it is read / written in
187: //the old format for compatibility
188: case Types.REAL:
189: case Types.FLOAT:
190: case Types.DOUBLE:
191: o = readReal(type);
192: break;
193:
194: case Types.NUMERIC:
195: case Types.DECIMAL:
196: o = readDecimal();
197: break;
198:
199: case Types.DATE:
200: o = readDate();
201: break;
202:
203: case Types.TIME:
204: o = readTime();
205: break;
206:
207: case Types.TIMESTAMP:
208: o = readTimestamp();
209: break;
210:
211: case Types.BOOLEAN:
212: o = readBit();
213: break;
214:
215: case Types.OTHER:
216: o = readOther();
217: break;
218:
219: case Types.BINARY:
220: case Types.VARBINARY:
221: case Types.LONGVARBINARY:
222: o = readBinary(type);
223: break;
224:
225: default:
226: throw Trace.runtimeError(
227: Trace.UNSUPPORTED_INTERNAL_OPERATION,
228: "RowInputBase " + Types.getTypeString(type));
229: }
230:
231: data[i] = o;
232: }
233:
234: return data;
235: }
236:
237: /**
238: * Used to reset the row, ready for a new row to be written into the
239: * byte[] buffer by an external routine.
240: *
241: */
242: public void resetRow(int filepos, int rowsize) throws IOException {
243:
244: mark = 0;
245:
246: reset();
247:
248: if (buf.length < rowsize) {
249: buf = new byte[rowsize];
250: }
251:
252: filePos = filepos;
253: size = count = rowsize;
254: pos = 4;
255: buf[0] = (byte) ((rowsize >>> 24) & 0xFF);
256: buf[1] = (byte) ((rowsize >>> 16) & 0xFF);
257: buf[2] = (byte) ((rowsize >>> 8) & 0xFF);
258: buf[3] = (byte) ((rowsize >>> 0) & 0xFF);
259: }
260:
261: public byte[] getBuffer() {
262: return buf;
263: }
264:
265: public int skipBytes(int n) throws IOException {
266: throw Trace.runtimeError(Trace.UNSUPPORTED_INTERNAL_OPERATION,
267: "RowInputBase");
268: }
269:
270: public String readLine() throws IOException {
271: throw Trace.runtimeError(Trace.UNSUPPORTED_INTERNAL_OPERATION,
272: "RowInputBase");
273: }
274: }
|