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