KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > sql > UpdateRow


1 package com.quadcap.sql;
2
3 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.io.BufferedOutputStream JavaDoc;
42 import java.io.ByteArrayOutputStream JavaDoc;
43 import java.io.Externalizable JavaDoc;
44 import java.io.InputStream JavaDoc;
45 import java.io.IOException JavaDoc;
46 import java.io.ObjectInput JavaDoc;
47 import java.io.ObjectOutput JavaDoc;
48 import java.io.OutputStream JavaDoc;
49
50 import java.util.Vector JavaDoc;
51
52 import java.sql.SQLException JavaDoc;
53
54 import com.quadcap.sql.io.Arrays;
55 import com.quadcap.sql.io.ObjectInputStream;
56 import com.quadcap.sql.io.ObjectOutputStream;
57 import com.quadcap.sql.io.Extern;
58
59 import com.quadcap.sql.file.BlockFile;
60 import com.quadcap.sql.file.Datafile;
61 import com.quadcap.sql.file.Log;
62 import com.quadcap.sql.file.PageManager;
63 import com.quadcap.sql.file.SubPageManager;
64
65 import com.quadcap.sql.index.Btree;
66
67 import com.quadcap.sql.types.Value;
68 import com.quadcap.sql.types.ValueBlob;
69
70 import com.quadcap.util.Debug;
71 import com.quadcap.util.Util;
72
73 /**
74  * Log step to update one or more values in a table row.
75  *
76  * @author Stan Bailes
77  */

78 public class UpdateRow extends LogStep implements Externalizable JavaDoc {
79     transient Table table = null;
80
81     String JavaDoc tableName = null;
82     Row memRow;
83     Row oldRow;
84     byte[] rowBytes = null;
85     byte[] oldRowBytes = null;
86     long rowId = -1;
87
88     /**
89      * Default Constructor
90      */

91     public UpdateRow() {}
92
93     /**
94      * Construct update for specified table row
95      */

96     public UpdateRow(Session session, Table table, long rowId, Row row)
97     throws IOException JavaDoc, SQLException JavaDoc
98     {
99         super(session);
100         init(session, table, rowId, row);
101     }
102
103     /**
104      * Construct update where both old and new rows are already prepared.
105      */

106     public UpdateRow(Session session, long rowId, Row orow,
107                      Row nrow)
108     throws IOException JavaDoc, SQLException JavaDoc
109     {
110         super(session);
111         init(session, null, rowId, nrow);
112         oldRow = orow;
113     }
114
115     /**
116      * Construct update for specified table row
117      */

118     public UpdateRow(Session session, Table table, long rowId,
119                      byte[] oldRowBytes, byte[] rowBytes)
120     throws IOException JavaDoc, SQLException JavaDoc
121     {
122         super(session);
123         if (session.getDatabase().inMemory()) {
124             throw new SQLException JavaDoc("in Memory Database: internal error");
125         }
126         initx(table, rowId, oldRowBytes, rowBytes);
127     }
128
129     /**
130      * Special re=init for add/drop column
131      */

132     public void initx(Table table, long rowId, byte[] oldRowBytes,
133                      byte[] rowBytes) {
134     this.table = table;
135     this.tableName = table.getName();
136     this.rowBytes = copy(rowBytes);
137         this.oldRowBytes = copy(oldRowBytes);
138     this.rowId = rowId;
139     }
140
141     final byte[] copy(byte[] b) {
142         byte[] r = new byte[b.length];
143         System.arraycopy(b, 0, r, 0, b.length);
144         return r;
145     }
146     
147     /**
148      * Explicit init/reinit
149      */

150     public void init(Session session, Table table, long rowId, Row row)
151     throws IOException JavaDoc, SQLException JavaDoc
152     {
153     this.table = table;
154     this.tableName = table == null ? null : table.getName();
155         if (session.getDatabase().inMemory()) {
156             this.memRow = row;
157         } else {
158             this.rowBytes = LazyRow.writeRow(session, table, row);
159         }
160     this.rowId = rowId;
161     }
162
163     /**
164      * Lazy table accessor
165      */

166     Table getTable(Database db) throws IOException JavaDoc {
167     if (table == null && tableName != null) {
168         table = (Table)db.getRelation(tableName);
169     }
170     return table;
171     }
172
173     /**
174      * Instantiate the row from the serialized byte array (if necessary)
175      */

176     final LazyRow getRow(Datafile db) throws IOException JavaDoc, SQLException JavaDoc {
177         LazyRow r = new LazyRow(table.getColumnCount());
178         r.reset(rowBytes, db);
179     return r;
180     }
181
182     /**
183      * LogStep.redo(): blob accounting if necessary, then update the
184      * row in the database
185      */

186     public void redo(Session session) throws IOException JavaDoc, SQLException JavaDoc {
187     Database db = session.getDatabase();
188     BlockFile file = db.getFile();
189
190         if (session.getConnection().inRecovery()) {
191             Log log = session.getLog();
192             getTable(db);
193             
194             // The row may contain blobs which have been mapped.
195
if (table.hasBlobs()) {
196                 boolean anyChanged = false;
197                 Row row = getRow(db);
198                 for (int i = 1; i <= row.size(); i++) {
199                     Value v = row.item(i);
200                     if (v instanceof ValueBlob) {
201                         ValueBlob vb = (ValueBlob)v;
202                         long blk = vb.getPermBlock();
203                         long blk2 = log.getRowMap(blk);
204                         if (blk != blk2) {
205                             vb.setPermBlock(blk2);
206                             anyChanged = true;
207                         }
208                     }
209                 }
210                 if (anyChanged) {
211                     row.set(1, row.item(1));
212                     if (!db.inMemory()) {
213                         this.rowBytes = LazyRow.writeRow(session, table, row);
214                     }
215                 }
216             }
217             rowId = log.getRowMap(rowId);
218         }
219         if (db.inMemory()) {
220             db.putRow(session, getTable(db), rowId, memRow);
221         } else {
222             file.updateBytes(rowId, rowBytes);
223         }
224         session.incrUpdateCount();
225     }
226
227     /**
228      * LogStep.do(): blob accounting if necessary, then restore the
229      * old row in the database
230      */

231     public void undo(Session session) throws IOException JavaDoc, SQLException JavaDoc {
232         Database db = session.getDatabase();
233     BlockFile file = db.getFile();
234     Log log = session.getLog();
235
236         long actualRowId = log.getRowMap(rowId);
237         if (db.inMemory()) {
238             db.putRow(session, getTable(db), rowId, oldRow);
239         } else {
240             file.updateBytes(actualRowId, oldRowBytes);
241         }
242         session.decrUpdateCount();
243     }
244
245     /**
246      * Get ready...
247      */

248     public void prepare(Session session) throws SQLException JavaDoc, IOException JavaDoc {
249         if (session.getDatabase().inMemory()) {
250             if (oldRow == null) {
251                 oldRow = table.getRow(session.getDatabase(), rowId);
252             }
253         } else {
254             if (oldRowBytes == null) {
255                 oldRowBytes = session.getFile().getBytes(rowId);
256             }
257         }
258     }
259
260     /**
261      * Read me from a stream
262      */

263     public void readExternal(ObjectInput JavaDoc in)
264     throws IOException JavaDoc, ClassNotFoundException JavaDoc
265     {
266     super.readExternal(in);
267     tableName = (String JavaDoc)in.readObject();
268     rowId = in.readLong();
269     
270     rowBytes = Arrays.readBytes(in);
271     oldRowBytes = Arrays.readBytes(in);
272
273     }
274
275     /**
276      * Write me to a stream
277      */

278     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc {
279     super.writeExternal(out);
280     out.writeObject(tableName);
281     out.writeLong(rowId);
282
283     Arrays.writeBytes(out, rowBytes);
284     Arrays.writeBytes(out, oldRowBytes);
285
286     }
287
288     //#ifdef DEBUG
289
/**
290      * Return a string representation for debugging
291      */

292     public String JavaDoc toString() {
293     StringBuffer JavaDoc sb = new StringBuffer JavaDoc(super.toString());
294         sb.append(" UpdateRow(");
295     sb.append(SubPageManager.toString(rowId));
296         if (true) {
297             sb.append(",[");
298             sb.append(Util.hexBytes(oldRowBytes));
299             sb.append("] -> [");
300             sb.append(Util.hexBytes(rowBytes));
301             sb.append("]");
302         }
303     sb.append(')');
304     return sb.toString();
305     }
306     //#endif
307

308     /**
309      * My class's Extern object
310      */

311     static Extern extern;
312     public void setExtern(Extern extern) { UpdateRow.extern = extern; }
313     public Extern getExtern() { return extern; }
314 }
315
Popular Tags