001: package com.quadcap.sql;
002:
003: /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
004: *
005: * This software is distributed under the Quadcap Free Software License.
006: * This software may be used or modified for any purpose, personal or
007: * commercial. Open Source redistributions are permitted. Commercial
008: * redistribution of larger works derived from, or works which bundle
009: * this software requires a "Commercial Redistribution License"; see
010: * http://www.quadcap.com/purchase.
011: *
012: * Redistributions qualify as "Open Source" under one of the following terms:
013: *
014: * Redistributions are made at no charge beyond the reasonable cost of
015: * materials and delivery.
016: *
017: * Redistributions are accompanied by a copy of the Source Code or by an
018: * irrevocable offer to provide a copy of the Source Code for up to three
019: * years at the cost of materials and delivery. Such redistributions
020: * must allow further use, modification, and redistribution of the Source
021: * Code under substantially the same terms as this license.
022: *
023: * Redistributions of source code must retain the copyright notices as they
024: * appear in each source code file, these license terms, and the
025: * disclaimer/limitation of liability set forth as paragraph 6 below.
026: *
027: * Redistributions in binary form must reproduce this Copyright Notice,
028: * these license terms, and the disclaimer/limitation of liability set
029: * forth as paragraph 6 below, in the documentation and/or other materials
030: * provided with the distribution.
031: *
032: * The Software is provided on an "AS IS" basis. No warranty is
033: * provided that the Software is free of defects, or fit for a
034: * particular purpose.
035: *
036: * Limitation of Liability. Quadcap Software shall not be liable
037: * for any damages suffered by the Licensee or any third party resulting
038: * from use of the Software.
039: */
040:
041: import java.io.ByteArrayInputStream;
042: import java.io.IOException;
043:
044: import java.sql.SQLException;
045:
046: import com.quadcap.sql.io.ObjectInputStream;
047: import com.quadcap.sql.io.ObjectOutputStream;
048:
049: import com.quadcap.sql.types.Type;
050: import com.quadcap.sql.types.Value;
051:
052: import com.quadcap.sql.file.ByteArrayRandomAccess;
053: import com.quadcap.sql.file.Datafile;
054: import com.quadcap.sql.file.PageManager;
055: import com.quadcap.sql.file.RandomAccess;
056: import com.quadcap.sql.file.RandomAccessOutputStream;
057: import com.quadcap.sql.file.SubPageManager;
058:
059: import com.quadcap.util.Debug;
060: import com.quadcap.util.Util;
061:
062: /**
063: * A row that we deserialize only as needed to produce values.
064: *
065: * @author Stan Bailes
066: */
067: public class LazyRow extends Row {
068: ByteArrayRandomAccess ra;
069: boolean[] dirty;
070:
071: public LazyRow(int size) {
072: super (size);
073: this .dirty = new boolean[size + 1];
074: }
075:
076: public void reset(RandomAccess rowBuf, Datafile db)
077: throws IOException, SQLException {
078: resetDirty();
079: if (ra == null) {
080: ra = new ByteArrayRandomAccess((int) rowBuf.size());
081: }
082: ra.resize(rowBuf.size());
083: byte[] buf = ra.getBytes();
084: rowBuf.read(0, buf, 0, (int) rowBuf.size());
085: bulkLoad(db);
086: }
087:
088: public void reset(byte[] buf, Datafile db) throws IOException,
089: SQLException {
090: resetDirty();
091: if (ra == null) {
092: ra = new ByteArrayRandomAccess(buf);
093: } else {
094: ra.reset(buf, buf.length);
095: }
096: bulkLoad(db);
097: }
098:
099: final void bulkLoad(Datafile db) throws SQLException {
100: try {
101: ByteArrayInputStream bi = new ByteArrayInputStream(
102: getBytes());
103: ObjectInputStream oi = new ObjectInputStream(bi);
104: int rsize = oi.readInt();
105: if (rsize != size()) {
106: throw new RuntimeException("Bad row size: " + rsize
107: + " vs tuple size: " + size());
108: }
109: this .blobCnt = oi.readInt();
110: for (int i = 1; i <= rsize; i++) {
111: Value vx = (Value) oi.readObject();
112: if (db != null)
113: vx.setDatafile(db);
114: set(i, vx);
115: dirty[i] = false;
116: }
117: } catch (Throwable e) {
118: throw DbException.wrapThrowable(e);
119: }
120: }
121:
122: public final void resetDirty() {
123: for (int i = 1; i <= size(); i++) {
124: dirty[i] = false;
125: }
126: }
127:
128: final boolean isDirty() {
129: boolean d = false;
130: for (int i = 1; i < dirty.length && !d; i++) {
131: d = dirty[i];
132: }
133: return d;
134: }
135:
136: public void set(int i, Value v) throws SQLException {
137: super .set(i, v);
138: dirty[i] = true;
139: }
140:
141: final byte[] getBytes() throws IOException {
142: byte[] ret = ra.getBytes();
143: return ret;
144: }
145:
146: final static byte[] writeRow(Session session, Tuple tuple, Row row)
147: throws IOException, SQLException {
148: if (row instanceof LazyRow) {
149: LazyRow lrow = (LazyRow) row;
150: if (!lrow.isDirty()) {
151: byte[] buf = lrow.getBytes();
152: return buf;
153: }
154: }
155: ObjectOutputStream out = session.oos;
156: out.reset(null);
157: writeRow(tuple, row, out);
158: byte[] ret = out.toByteArray();
159: return ret;
160: }
161:
162: //#ifdef DEBUG
163: final static String tn(Value v) throws SQLException {
164: StringBuffer sb = new StringBuffer(v.getType().toString());
165: sb.append(":");
166: sb.append(com.quadcap.sql.types.Value.tn(v));
167: sb.append("(=");
168: sb.append(String.valueOf(v));
169: sb.append(')');
170: return sb.toString();
171: }
172:
173: //#endif
174:
175: final static void writeRow(Tuple tuple, Row row,
176: ObjectOutputStream out) throws IOException, SQLException {
177: out.writeInt(row.size());
178: out.writeInt(row.blobCnt);
179: for (int i = 1; i <= row.size(); i++) {
180: Value vx = row.item(i);
181: if (tuple != null) {
182: Type t = tuple.getColumn(i).getType();
183: Value v1 = t.convert(vx);
184: vx = v1;
185: }
186: out.writeObject(vx);
187: }
188: }
189: }
|