1 /* Copyright (c) 2001-2016, The HSQL Development Group
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the HSQL Development Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 
32 package org.hsqldb.rowio;
33 
34 import java.math.BigDecimal;
35 
36 import org.hsqldb.error.Error;
37 import org.hsqldb.error.ErrorCode;
38 import org.hsqldb.lib.HsqlByteArrayInputStream;
39 import org.hsqldb.types.BinaryData;
40 import org.hsqldb.types.BlobData;
41 import org.hsqldb.types.ClobData;
42 import org.hsqldb.types.IntervalMonthData;
43 import org.hsqldb.types.IntervalSecondData;
44 import org.hsqldb.types.TimeData;
45 import org.hsqldb.types.TimestampData;
46 import org.hsqldb.types.Type;
47 import org.hsqldb.types.Types;
48 
49 /**
50  * Base class for reading the data for a database row in different formats.
51  * Defines the methods that are independent of storage format and declares
52  * the format-dependent methods that subclasses should define.
53  *
54  * @author Bob Preston (sqlbob@users dot sourceforge.net)
55  * @author Fred Toussi (fredt@users dot sourceforge.net)
56  * @version 2.3.3
57  * @since 1.7.0
58  */
59 abstract class RowInputBase extends HsqlByteArrayInputStream {
60 
61     static final int NO_POS = -1;
62 
63     // fredt - initialisation may be unnecessary as it's done in resetRow()
64     protected long filePos = NO_POS;
65     protected int  size;
66 
RowInputBase()67     RowInputBase() {
68         this(new byte[4]);
69     }
70 
RowInputBase(int size)71     RowInputBase(int size) {
72         this(new byte[size]);
73     }
74 
75     /**
76      * Constructor takes a complete row
77      */
RowInputBase(byte[] buf)78     RowInputBase(byte[] buf) {
79 
80         super(buf);
81 
82         size = buf.length;
83     }
84 
getPos()85     public long getPos() {
86 
87         if (filePos == NO_POS) {
88 
89 //                Trace.printSystemOut(Trace.DatabaseRowInput_getPos);
90         }
91 
92         return filePos;
93     }
94 
getSize()95     public int getSize() {
96         return size;
97     }
98 
99 // fredt@users - comment - methods used for node and type data
readType()100     public abstract int readType();
101 
readString()102     public abstract String readString();
103 
104 // fredt@users - comment - methods used for SQL types
readNull()105     protected abstract boolean readNull();
106 
readChar(Type type)107     protected abstract String readChar(Type type);
108 
readSmallint()109     protected abstract Integer readSmallint();
110 
readInteger()111     protected abstract Integer readInteger();
112 
readBigint()113     protected abstract Long readBigint();
114 
readReal()115     protected abstract Double readReal();
116 
readDecimal(Type type)117     protected abstract BigDecimal readDecimal(Type type);
118 
readBoole()119     protected abstract Boolean readBoole();
120 
readTime(Type type)121     protected abstract TimeData readTime(Type type);
122 
readDate(Type type)123     protected abstract TimestampData readDate(Type type);
124 
readTimestamp(Type type)125     protected abstract TimestampData readTimestamp(Type type);
126 
readYearMonthInterval(Type type)127     protected abstract IntervalMonthData readYearMonthInterval(Type type);
128 
readDaySecondInterval(Type type)129     protected abstract IntervalSecondData readDaySecondInterval(Type type);
130 
readOther()131     protected abstract Object readOther();
132 
readBinary()133     protected abstract BinaryData readBinary();
134 
readBit()135     protected abstract BinaryData readBit();
136 
readClob()137     protected abstract ClobData readClob();
138 
readBlob()139     protected abstract BlobData readBlob();
140 
readArray(Type type)141     protected abstract Object[] readArray(Type type);
142 
143     /**
144      *  reads row data from a stream using the JDBC types in colTypes
145      *
146      * @param  colTypes
147      * @throws  IOException
148      */
readData(Type[] colTypes)149     public Object[] readData(Type[] colTypes) {
150 
151         int      l    = colTypes.length;
152         Object[] data = new Object[l];
153 
154         for (int i = 0; i < l; i++) {
155             Type type = colTypes[i];
156 
157             data[i] = readData(type);
158         }
159 
160         return data;
161     }
162 
readData(Type type)163     public Object readData(Type type) {
164 
165         Object o = null;
166 
167         if (readNull()) {
168             return null;
169         }
170 
171         switch (type.typeCode) {
172 
173             case Types.SQL_ALL_TYPES :
174                 break;
175 
176             case Types.SQL_CHAR :
177             case Types.SQL_VARCHAR :
178                 o = readChar(type);
179                 break;
180 
181             case Types.TINYINT :
182             case Types.SQL_SMALLINT :
183                 o = readSmallint();
184                 break;
185 
186             case Types.SQL_INTEGER :
187                 o = readInteger();
188                 break;
189 
190             case Types.SQL_BIGINT :
191                 o = readBigint();
192                 break;
193 
194             case Types.SQL_REAL :
195             case Types.SQL_FLOAT :
196             case Types.SQL_DOUBLE :
197                 o = readReal();
198                 break;
199 
200             case Types.SQL_NUMERIC :
201             case Types.SQL_DECIMAL :
202                 o = readDecimal(type);
203                 break;
204 
205             case Types.SQL_DATE :
206                 o = readDate(type);
207                 break;
208 
209             case Types.SQL_TIME :
210             case Types.SQL_TIME_WITH_TIME_ZONE :
211                 o = readTime(type);
212                 break;
213 
214             case Types.SQL_TIMESTAMP :
215             case Types.SQL_TIMESTAMP_WITH_TIME_ZONE :
216                 o = readTimestamp(type);
217                 break;
218 
219             case Types.SQL_INTERVAL_YEAR :
220             case Types.SQL_INTERVAL_YEAR_TO_MONTH :
221             case Types.SQL_INTERVAL_MONTH :
222                 o = readYearMonthInterval(type);
223                 break;
224 
225             case Types.SQL_INTERVAL_DAY :
226             case Types.SQL_INTERVAL_DAY_TO_HOUR :
227             case Types.SQL_INTERVAL_DAY_TO_MINUTE :
228             case Types.SQL_INTERVAL_DAY_TO_SECOND :
229             case Types.SQL_INTERVAL_HOUR :
230             case Types.SQL_INTERVAL_HOUR_TO_MINUTE :
231             case Types.SQL_INTERVAL_HOUR_TO_SECOND :
232             case Types.SQL_INTERVAL_MINUTE :
233             case Types.SQL_INTERVAL_MINUTE_TO_SECOND :
234             case Types.SQL_INTERVAL_SECOND :
235                 o = readDaySecondInterval(type);
236                 break;
237 
238             case Types.SQL_BOOLEAN :
239                 o = readBoole();
240                 break;
241 
242             case Types.OTHER :
243                 o = readOther();
244                 break;
245 
246             case Types.SQL_CLOB :
247                 o = readClob();
248                 break;
249 
250             case Types.SQL_BLOB :
251                 o = readBlob();
252                 break;
253 
254             case Types.SQL_ARRAY :
255                 o = readArray(type);
256                 break;
257 
258             case Types.SQL_GUID :
259             case Types.SQL_BINARY :
260             case Types.SQL_VARBINARY :
261                 o = readBinary();
262                 break;
263 
264             case Types.SQL_BIT :
265             case Types.SQL_BIT_VARYING :
266                 o = readBit();
267                 break;
268 
269             default :
270                 throw Error.runtimeError(ErrorCode.U_S0500,
271                                          "RowInputBase - "
272                                          + type.getNameString());
273         }
274 
275         return o;
276     }
277 
278     /**
279      *  Used to reset the row, ready for a new row to be written into the
280      *  byte[] buffer by an external routine.
281      *
282      */
resetRow(long filepos, int rowsize)283     public void resetRow(long filepos, int rowsize) {
284 
285         mark = 0;
286 
287         reset();
288 
289         if (buffer.length < rowsize) {
290             buffer = new byte[rowsize];
291         }
292 
293         filePos   = filepos;
294         size      = count = rowsize;
295         pos       = 4;
296         buffer[0] = (byte) ((rowsize >>> 24) & 0xFF);
297         buffer[1] = (byte) ((rowsize >>> 16) & 0xFF);
298         buffer[2] = (byte) ((rowsize >>> 8) & 0xFF);
299         buffer[3] = (byte) ((rowsize >>> 0) & 0xFF);
300     }
301 
302     /**
303      *  Used to reset the row, ready for a new row to be written into the
304      *  byte[] buffer by an external routine.
305      *
306      */
resetBlock(long filepos, int rowsize)307     public void resetBlock(long filepos, int rowsize) {
308 
309         mark = 0;
310 
311         reset();
312 
313         if (buffer.length < rowsize) {
314             buffer = new byte[rowsize];
315         }
316 
317         filePos = filepos;
318         size    = count = rowsize;
319     }
320 
getBuffer()321     public byte[] getBuffer() {
322         return buffer;
323     }
324 
skipBytes(int n)325     public int skipBytes(int n) {
326         throw Error.runtimeError(ErrorCode.U_S0500, "RowInputBase");
327     }
328 
readLine()329     public String readLine() {
330         throw Error.runtimeError(ErrorCode.U_S0500, "RowInputBase");
331     }
332 }
333