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