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.math.BigDecimal;
034: import java.sql.Date;
035: import java.sql.Time;
036: import java.sql.Timestamp;
037:
038: import org.hsqldb.Column;
039: import org.hsqldb.Table;
040: import org.hsqldb.Trace;
041: import org.hsqldb.Types;
042: import org.hsqldb.lib.HashMappedList;
043: import org.hsqldb.lib.HsqlByteArrayOutputStream;
044: import org.hsqldb.types.Binary;
045: import org.hsqldb.types.JavaObject;
046:
047: /**
048: * Base class for writing the data for a database row in different formats.
049: * Defines the methods that are independent of storage format and declares
050: * the format-dependent methods that subclasses should define.
051: *
052: * @author sqlbob@users (RMP)
053: * @author fredt@users
054: * @version 1.7.2
055: * @since 1.7.0
056: */
057: public abstract class RowOutputBase extends HsqlByteArrayOutputStream
058: implements RowOutputInterface {
059:
060: public static final int CACHED_ROW_160 = 0;
061: public static final int CACHED_ROW_170 = 1;
062:
063: // the last column in a table is an ID that should not be written to file
064: protected boolean skipSystemId = false;
065:
066: /**
067: * Constructor used for persistent storage of a Table row
068: *
069: * @exception IOException when an IO error is encountered
070: */
071: public RowOutputBase() {
072: super ();
073: }
074:
075: /**
076: * Constructor used for result sets
077: *
078: * @exception IOException when an IO error is encountered
079: */
080: public RowOutputBase(int initialSize) {
081: super (initialSize);
082: }
083:
084: /**
085: * Constructor used for network transmission of result sets
086: *
087: * @exception IOException when an IO error is encountered
088: */
089: public RowOutputBase(byte[] buffer) {
090: super (buffer);
091: }
092:
093: // fredt@users - comment - methods for writing Result column type, name and data size
094: public abstract void writeEnd();
095:
096: public abstract void writeSize(int size);
097:
098: public abstract void writeType(int type);
099:
100: public abstract void writeShortData(short i);
101:
102: public abstract void writeIntData(int i);
103:
104: public abstract void writeIntData(int i, int position);
105:
106: public abstract void writeString(String s);
107:
108: // fredt@users - comment - methods used for writing each SQL type
109: protected void writeFieldPrefix() {
110: }
111:
112: protected abstract void writeFieldType(int type);
113:
114: protected abstract void writeNull(int type);
115:
116: protected abstract void writeChar(String s, int t);
117:
118: protected abstract void writeSmallint(Number o);
119:
120: protected abstract void writeInteger(Number o);
121:
122: protected abstract void writeBigint(Number o);
123:
124: protected abstract void writeReal(Double o, int type);
125:
126: protected abstract void writeDecimal(BigDecimal o);
127:
128: protected abstract void writeBit(Boolean o);
129:
130: protected abstract void writeDate(Date o);
131:
132: protected abstract void writeTime(Time o);
133:
134: protected abstract void writeTimestamp(Timestamp o);
135:
136: protected abstract void writeOther(JavaObject o);
137:
138: protected abstract void writeBinary(Binary o, int t);
139:
140: public void writeRow(Object[] data, Table t) {
141:
142: writeSize(0);
143: writeData(data, t);
144: writeIntData(size(), 0);
145: }
146:
147: /**
148: * This method is called to write data for a table.
149: *
150: * @param data
151: * @param t
152: * @throws IOException
153: */
154: public void writeData(Object[] data, Table t) {
155:
156: int[] types = t.getColumnTypes();
157: int l = t.getColumnCount();
158:
159: writeData(l, types, data, null, null);
160: }
161:
162: /**
163: * This method is called to write data for a Result.
164: *
165: * @param l
166: * @param types
167: * @param data
168: * @param cols
169: * @param primarykeys
170: * @throws IOException
171: */
172: public void writeData(int l, int[] types, Object[] data,
173: HashMappedList cols, int[] primaryKeys) {
174:
175: boolean hasPK = primaryKeys != null && primaryKeys.length != 0;
176: int limit = hasPK ? primaryKeys.length : l;
177:
178: for (int i = 0; i < limit; i++) {
179: int j = hasPK ? primaryKeys[i] : i;
180: Object o = data[j];
181: int t = types[j];
182:
183: if (cols != null) {
184: Column col = (Column) cols.get(j);
185:
186: writeFieldPrefix();
187: writeString(col.columnName.statementName);
188: }
189:
190: if (o == null) {
191: writeNull(t);
192:
193: continue;
194: }
195:
196: writeFieldType(t);
197:
198: switch (t) {
199:
200: case Types.NULL:
201: case Types.CHAR:
202: case Types.VARCHAR:
203: case Types.VARCHAR_IGNORECASE:
204: case Types.LONGVARCHAR:
205: writeChar((String) o, t);
206: break;
207:
208: case Types.TINYINT:
209: case Types.SMALLINT:
210: writeSmallint((Number) o);
211: break;
212:
213: case Types.INTEGER:
214: writeInteger((Number) o);
215: break;
216:
217: case Types.BIGINT:
218: writeBigint((Number) o);
219: break;
220:
221: case Types.REAL:
222: case Types.FLOAT:
223: case Types.DOUBLE:
224: writeReal((Double) o, t);
225: break;
226:
227: case Types.NUMERIC:
228: case Types.DECIMAL:
229: writeDecimal((BigDecimal) o);
230: break;
231:
232: case Types.BOOLEAN:
233: writeBit((Boolean) o);
234: break;
235:
236: case Types.DATE:
237: writeDate((Date) o);
238: break;
239:
240: case Types.TIME:
241: writeTime((Time) o);
242: break;
243:
244: case Types.TIMESTAMP:
245: writeTimestamp((Timestamp) o);
246: break;
247:
248: case Types.OTHER:
249: writeOther((JavaObject) o);
250: break;
251:
252: case Types.BINARY:
253: case Types.VARBINARY:
254: case Types.LONGVARBINARY:
255: writeBinary((Binary) o, t);
256: break;
257:
258: default:
259: throw Trace.runtimeError(Trace.FUNCTION_NOT_SUPPORTED,
260: Types.getTypeString(t));
261: }
262: }
263: }
264:
265: // returns the underlying HsqlByteArrayOutputStream
266: public HsqlByteArrayOutputStream getOutputStream() {
267: return this;
268: }
269: }
|