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.ColumnSchema; 37 import org.hsqldb.Row; 38 import org.hsqldb.error.Error; 39 import org.hsqldb.error.ErrorCode; 40 import org.hsqldb.lib.HashMappedList; 41 import org.hsqldb.lib.HsqlByteArrayOutputStream; 42 import org.hsqldb.types.BinaryData; 43 import org.hsqldb.types.BlobData; 44 import org.hsqldb.types.ClobData; 45 import org.hsqldb.types.IntervalMonthData; 46 import org.hsqldb.types.IntervalSecondData; 47 import org.hsqldb.types.JavaObjectData; 48 import org.hsqldb.types.TimeData; 49 import org.hsqldb.types.TimestampData; 50 import org.hsqldb.types.Type; 51 import org.hsqldb.types.Types; 52 53 /** 54 * Base class for writing the data for a database row in different formats. 55 * Defines the methods that are independent of storage format and declares 56 * the format-dependent methods that subclasses should define. 57 * 58 * @author Bob Preston (sqlbob@users dot sourceforge.net) 59 * @author Fred Toussi (fredt@users dot sourceforge.net) 60 * @version 2.3.3 61 * @since 1.7.0 62 */ 63 abstract class RowOutputBase extends HsqlByteArrayOutputStream 64 implements RowOutputInterface { 65 66 public static final int CACHED_ROW_160 = 0; 67 public static final int CACHED_ROW_170 = 1; 68 69 // the last column in a table is an ID that should not be written to file 70 protected boolean skipSystemId = false; 71 72 /** 73 * Constructor used for persistent storage of a Table row 74 * 75 * @exception IOException when an IO error is encountered 76 */ RowOutputBase()77 public RowOutputBase() { 78 super(); 79 } 80 81 /** 82 * Constructor used for result sets 83 * 84 * @exception IOException when an IO error is encountered 85 */ RowOutputBase(int initialSize)86 public RowOutputBase(int initialSize) { 87 super(initialSize); 88 } 89 90 /** 91 * Constructor used for network transmission of result sets 92 * 93 * @exception IOException when an IO error is encountered 94 */ RowOutputBase(byte[] buffer)95 public RowOutputBase(byte[] buffer) { 96 super(buffer); 97 } 98 setStorageSize(int size)99 public abstract void setStorageSize(int size); 100 101 // fredt@users - comment - methods for writing Result column type, name and data size writeEnd()102 public abstract void writeEnd(); 103 writeSize(int size)104 public abstract void writeSize(int size); 105 writeType(int type)106 public abstract void writeType(int type); 107 writeString(String s)108 public abstract void writeString(String s); 109 110 // fredt@users - comment - methods used for writing each SQL type writeFieldPrefix()111 protected void writeFieldPrefix() {} 112 writeFieldType(Type type)113 protected abstract void writeFieldType(Type type); 114 writeNull(Type type)115 protected abstract void writeNull(Type type); 116 writeChar(String s, Type t)117 protected abstract void writeChar(String s, Type t); 118 writeSmallint(Number o)119 protected abstract void writeSmallint(Number o); 120 writeInteger(Number o)121 protected abstract void writeInteger(Number o); 122 writeBigint(Number o)123 protected abstract void writeBigint(Number o); 124 writeReal(Double o)125 protected abstract void writeReal(Double o); 126 writeDecimal(BigDecimal o, Type type)127 protected abstract void writeDecimal(BigDecimal o, Type type); 128 writeBoolean(Boolean o)129 protected abstract void writeBoolean(Boolean o); 130 writeDate(TimestampData o, Type type)131 protected abstract void writeDate(TimestampData o, Type type); 132 writeTime(TimeData o, Type type)133 protected abstract void writeTime(TimeData o, Type type); 134 writeTimestamp(TimestampData o, Type type)135 protected abstract void writeTimestamp(TimestampData o, Type type); 136 writeYearMonthInterval(IntervalMonthData o, Type type)137 protected abstract void writeYearMonthInterval(IntervalMonthData o, 138 Type type); 139 writeDaySecondInterval(IntervalSecondData o, Type type)140 protected abstract void writeDaySecondInterval(IntervalSecondData o, 141 Type type); 142 writeOther(JavaObjectData o)143 protected abstract void writeOther(JavaObjectData o); 144 writeBit(BinaryData o)145 protected abstract void writeBit(BinaryData o); 146 writeBinary(BinaryData o)147 protected abstract void writeBinary(BinaryData o); 148 writeClob(ClobData o, Type type)149 protected abstract void writeClob(ClobData o, Type type); 150 writeBlob(BlobData o, Type type)151 protected abstract void writeBlob(BlobData o, Type type); 152 writeArray(Object[] o, Type type)153 protected abstract void writeArray(Object[] o, Type type); 154 155 /** 156 * This method is called to write data for a table row. 157 */ writeData(Row row, Type[] types)158 public void writeData(Row row, Type[] types) { 159 writeData(types.length, types, row.getData(), null, null); 160 } 161 162 /** 163 * This method is called directly to write data for a delete statement. 164 */ writeData(int l, Type[] types, Object[] data, HashMappedList cols, int[] primaryKeys)165 public void writeData(int l, Type[] types, Object[] data, 166 HashMappedList cols, int[] primaryKeys) { 167 168 boolean hasPK = primaryKeys != null && primaryKeys.length != 0; 169 int limit = hasPK ? primaryKeys.length 170 : l; 171 172 for (int i = 0; i < limit; i++) { 173 int j = hasPK ? primaryKeys[i] 174 : i; 175 Object o = data[j]; 176 Type t = types[j]; 177 178 if (cols != null) { 179 ColumnSchema col = (ColumnSchema) cols.get(j); 180 181 writeFieldPrefix(); 182 writeString(col.getName().statementName); 183 } 184 185 writeData(o, t); 186 } 187 } 188 writeData(Object o, Type t)189 public void writeData(Object o, Type t) { 190 191 if (o == null) { 192 writeNull(t); 193 194 return; 195 } 196 197 writeFieldType(t); 198 199 switch (t.typeCode) { 200 201 case Types.SQL_ALL_TYPES : 202 break; 203 204 case Types.SQL_CHAR : 205 case Types.SQL_VARCHAR : 206 writeChar((String) o, t); 207 break; 208 209 case Types.TINYINT : 210 case Types.SQL_SMALLINT : 211 writeSmallint((Number) o); 212 break; 213 214 case Types.SQL_INTEGER : 215 writeInteger((Number) o); 216 break; 217 218 case Types.SQL_BIGINT : 219 writeBigint((Number) o); 220 break; 221 222 case Types.SQL_REAL : 223 case Types.SQL_FLOAT : 224 case Types.SQL_DOUBLE : 225 writeReal((Double) o); 226 break; 227 228 case Types.SQL_NUMERIC : 229 case Types.SQL_DECIMAL : 230 writeDecimal((BigDecimal) o, t); 231 break; 232 233 case Types.SQL_BOOLEAN : 234 writeBoolean((Boolean) o); 235 break; 236 237 case Types.SQL_DATE : 238 writeDate((TimestampData) o, t); 239 break; 240 241 case Types.SQL_TIME : 242 case Types.SQL_TIME_WITH_TIME_ZONE : 243 writeTime((TimeData) o, t); 244 break; 245 246 case Types.SQL_TIMESTAMP : 247 case Types.SQL_TIMESTAMP_WITH_TIME_ZONE : 248 writeTimestamp((TimestampData) o, t); 249 break; 250 251 case Types.SQL_INTERVAL_YEAR : 252 case Types.SQL_INTERVAL_YEAR_TO_MONTH : 253 case Types.SQL_INTERVAL_MONTH : 254 writeYearMonthInterval((IntervalMonthData) o, t); 255 break; 256 257 case Types.SQL_INTERVAL_DAY : 258 case Types.SQL_INTERVAL_DAY_TO_HOUR : 259 case Types.SQL_INTERVAL_DAY_TO_MINUTE : 260 case Types.SQL_INTERVAL_DAY_TO_SECOND : 261 case Types.SQL_INTERVAL_HOUR : 262 case Types.SQL_INTERVAL_HOUR_TO_MINUTE : 263 case Types.SQL_INTERVAL_HOUR_TO_SECOND : 264 case Types.SQL_INTERVAL_MINUTE : 265 case Types.SQL_INTERVAL_MINUTE_TO_SECOND : 266 case Types.SQL_INTERVAL_SECOND : 267 writeDaySecondInterval((IntervalSecondData) o, t); 268 break; 269 270 case Types.OTHER : 271 writeOther((JavaObjectData) o); 272 break; 273 274 case Types.SQL_BLOB : 275 writeBlob((BlobData) o, t); 276 break; 277 278 case Types.SQL_CLOB : 279 writeClob((ClobData) o, t); 280 break; 281 282 case Types.SQL_ARRAY : 283 writeArray((Object[]) o, t); 284 break; 285 286 case Types.SQL_GUID : 287 case Types.SQL_BINARY : 288 case Types.SQL_VARBINARY : 289 writeBinary((BinaryData) o); 290 break; 291 292 case Types.SQL_BIT : 293 case Types.SQL_BIT_VARYING : 294 writeBit((BinaryData) o); 295 break; 296 297 default : 298 throw Error.runtimeError(ErrorCode.U_S0500, 299 "RowOutputBase - " 300 + t.getNameString()); 301 } 302 } 303 304 // returns the underlying HsqlByteArrayOutputStream getOutputStream()305 public HsqlByteArrayOutputStream getOutputStream() { 306 return this; 307 } 308 duplicate()309 public abstract RowOutputInterface duplicate(); 310 } 311