KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > store > raw > data > DeleteOperation


1 /*
2
3    Derby - Class org.apache.derby.impl.store.raw.data.DeleteOperation
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.store.raw.data;
23
24 import org.apache.derby.iapi.reference.SQLState;
25
26 import org.apache.derby.iapi.services.sanity.SanityManager;
27 import org.apache.derby.iapi.services.io.FormatIdUtil;
28 import org.apache.derby.iapi.services.io.StoredFormatIds;
29
30 import org.apache.derby.impl.store.raw.data.BasePage;
31
32 import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;
33
34 import org.apache.derby.iapi.store.raw.Compensation;
35 import org.apache.derby.iapi.store.raw.Page;
36 import org.apache.derby.iapi.store.raw.RecordHandle;
37 import org.apache.derby.iapi.store.raw.Transaction;
38 import org.apache.derby.iapi.store.raw.xact.RawTransaction;
39
40 import org.apache.derby.iapi.store.raw.log.LogInstant;
41
42 import org.apache.derby.iapi.error.StandardException;
43
44 import org.apache.derby.iapi.types.DataValueDescriptor;
45
46 import org.apache.derby.iapi.services.io.CompressedNumber;
47 import org.apache.derby.iapi.services.io.FormatableBitSet;
48 import org.apache.derby.iapi.util.ByteArray;
49 import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream;
50
51 import java.io.OutputStream JavaDoc;
52 import java.io.ObjectOutput JavaDoc;
53 import java.io.ObjectInput JavaDoc;
54 import java.io.IOException JavaDoc;
55 import org.apache.derby.iapi.services.io.LimitObjectInput;
56
57
58 /**
59     Represents a delete (or undelete) of a record in a page.
60
61     <PRE>
62     @format_id LOGOP_DELETE
63         the formatId is written by FormatIdOutputStream when this object is
64         written out by writeObject
65     @purpose delete a record from a page.
66     @upgrade
67     @disk_layout
68         LogicalPageOperation the super class
69         doMeSlot(CompressedInt) the slot of the record to delete
70         delete(boolean) if true, delete, else undelete
71
72         OptionalData if we need logical undo, write the row that was
73                             deleted as the optional data. If we don't need
74                             logical undo, no optional data
75     @end_format
76     </PRE>
77 */

78 public final class DeleteOperation extends LogicalPageOperation
79 {
80     protected int doMeSlot; // delete slot - only valid during a doMe() operation
81
protected boolean delete; // set record as deleted if true, undeleted if false
82

83     transient protected ByteArray preparedLog;
84
85     public DeleteOperation(RawTransaction t, BasePage page, int slot, int recordId,
86                            boolean delete, LogicalUndo undo)
87         throws StandardException
88     {
89         super(page, undo, recordId);
90
91         doMeSlot = slot;
92         this.delete = delete;
93
94         try {
95             writeOptionalDataToBuffer(t);
96         } catch (IOException JavaDoc ioe) {
97             throw StandardException.newException(
98                     SQLState.DATA_UNEXPECTED_EXCEPTION, ioe);
99         }
100     }
101
102     /*
103      * Formatable methods
104      */

105
106     // no-arg constructor, required by Formatable
107
public DeleteOperation() { super(); }
108
109     /**
110         Write this out.
111         @exception IOException error writing to log stream
112     */

113     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc
114     {
115         super.writeExternal(out);
116         CompressedNumber.writeInt(out, doMeSlot);
117         out.writeBoolean(delete);
118     }
119
120     /**
121         Read this in
122         @exception IOException error reading from log stream
123         @exception ClassNotFoundException log stream corrupted
124     */

125     public void readExternal(ObjectInput JavaDoc in)
126          throws IOException JavaDoc, ClassNotFoundException JavaDoc
127     {
128         super.readExternal(in);
129         doMeSlot = CompressedNumber.readInt(in);
130         delete = in.readBoolean();
131     }
132
133     /**
134         Return my format identifier.
135     */

136     public int getTypeFormatId() {
137         return StoredFormatIds.LOGOP_DELETE;
138     }
139
140     /*
141      * Loggable methods
142      */

143     /**
144         Mark the record as deleted on the page.
145
146         @exception IOException Can be thrown by any of the methods of ObjectInput.
147         @exception StandardException Standard Cloudscape policy.
148
149         @see org.apache.derby.iapi.store.raw.Loggable#doMe
150     */

151     public void doMe(Transaction xact, LogInstant instant, LimitObjectInput in)
152          throws StandardException, IOException JavaDoc
153     {
154         this.page.setDeleteStatus(instant, doMeSlot, delete);
155     }
156     
157     /*
158      * Undoable methods
159      */

160
161     /**
162         Mark the record as not deleted, and then fix up the in-memory copy
163         of the page.
164         All logical undo logic has already been taken care of by generateUndo.
165
166         @exception StandardException Thrown by methods I call
167         @exception IOException Thrown by methods I call
168
169         @see LogicalPageOperation#undoMe
170     */

171     public void undoMe(Transaction xact, BasePage undoPage, int undoRecordId,
172                        LogInstant CLRInstant, LimitObjectInput in)
173          throws StandardException, IOException JavaDoc
174     {
175
176         int slot =
177             undoPage.findRecordById(undoRecordId, Page.FIRST_SLOT_NUMBER);
178         
179         if (SanityManager.DEBUG)
180         {
181             // if the record Id has changed, the page had better changed
182
// this can only happen during recovery since in run time undo,
183
// this resetRecordHandle gets called and this object have the new
184
// page number and recordId
185
if (undoRecordId != this.recordId)
186                 if (undoPage.getPageNumber() == getPageId().getPageNumber())
187                     SanityManager.THROWASSERT(
188                             "recordId changed from " + this.recordId +
189                             " to " + undoRecordId +
190                             " but page number did not change " +
191                             undoPage.getPageNumber());
192
193             if (slot == -1)
194                 SanityManager.THROWASSERT(
195                     "recordId " +
196                     undoRecordId +
197                     " not found on page " +
198                     undoPage.getPageNumber() +
199                     undoPage);
200         }
201
202         undoPage.setDeleteStatus(CLRInstant, slot, !delete);
203
204         undoPage.setAuxObject(null);
205     }
206
207     /*
208      * LogicalUndoable methods
209      */

210
211
212     /**
213         Restore the row stored in the optional data of the log record.
214
215         @exception IOException error reading from log stream
216         @exception StandardException Standard Cloudscape error policy
217     */

218     public void restoreLoggedRow(
219     Object JavaDoc[] row,
220     LimitObjectInput in)
221         throws StandardException, IOException JavaDoc
222     {
223         Page p = null;
224
225         try {
226             // the optional data is written by the page in the same format it
227
// stores record on the page,
228
// only a page knows how to restore a logged row back to a storable row
229
// first get the page where the insert went even though the row may no
230
// longer be there
231
p = getContainer().getPage(getPageId().getPageNumber());
232
233
234             ((BasePage)p).restoreRecordFromStream(in, row);
235
236         } finally {
237
238             if (p != null) {
239                 p.unlatch();
240                 p = null;
241             }
242         }
243     }
244
245     /*
246      * PageBasicOperation method to support BeforeImageLogging
247      */

248
249     /**
250      * restore the before image of the page
251      *
252      * @exception StandardException Standard Cloudscape Error Policy
253      * @exception IOException problem reading the complete log record from the
254      * input stream
255      */

256     public void restoreMe(Transaction xact, BasePage undoPage, LogInstant CLRinstant, LimitObjectInput in)
257          throws StandardException, IOException JavaDoc
258     {
259         int slot = undoPage.findRecordById(recordId, Page.FIRST_SLOT_NUMBER);
260         if (SanityManager.DEBUG)
261         {
262             if ( ! getPageId().equals(undoPage.getPageId()))
263                 SanityManager.THROWASSERT(
264                                 "restoreMe cannot restore to a different page. "
265                                  + "doMe page:" + getPageId() + " undoPage:" +
266                                  undoPage.getPageId());
267             if (slot != doMeSlot)
268                 SanityManager.THROWASSERT(
269                                 "restoreMe cannot restore to a different slot. "
270                                  + "doMe slot:" + doMeSlot + " undoMe slot: " +
271                                  slot + " recordId:" + recordId);
272         }
273         undoPage.setDeleteStatus(CLRinstant, slot, !delete);
274         undoPage.setAuxObject(null);
275     }
276
277     /*
278         methods to support prepared log
279         
280         the following two methods should not be called during recover
281     */

282
283     public ByteArray getPreparedLog()
284     {
285         return (this.preparedLog);
286     }
287
288     /**
289         if logical undo, writes out the row that was deleted
290
291         @exception IOException Can be thrown by any of the methods of ObjectOutput
292         @exception StandardException Standard Cloudscape policy.
293     */

294     private void writeOptionalDataToBuffer(RawTransaction t)
295         throws StandardException, IOException JavaDoc
296     {
297
298         if (SanityManager.DEBUG) {
299             SanityManager.ASSERT(this.page != null);
300         }
301
302         DynamicByteArrayOutputStream logBuffer = t.getLogBuffer();
303         int optionalDataStart = logBuffer.getPosition();
304
305         if (SanityManager.DEBUG) {
306             SanityManager.ASSERT(optionalDataStart == 0,
307                 "Buffer for writing the optional data should start at position 0");
308         }
309
310         if (undo != null)
311             this.page.logRecord(doMeSlot, BasePage.LOG_RECORD_DEFAULT,
312                                 recordId, (FormatableBitSet) null, logBuffer,
313                                 (RecordHandle)null);
314         
315         int optionalDataLength = logBuffer.getPosition() - optionalDataStart;
316
317         if (SanityManager.DEBUG) {
318             if (optionalDataLength != logBuffer.getUsed())
319                 SanityManager.THROWASSERT("wrong optional data length, optionalDataLength = "
320                     + optionalDataLength + ", logBuffer.getUsed() = " + logBuffer.getUsed());
321         }
322
323         // set the position to the beginning of the buffer
324
logBuffer.setPosition(optionalDataStart);
325
326         this.preparedLog = new ByteArray(logBuffer.getByteArray(), optionalDataStart,
327             optionalDataLength);
328
329     }
330
331     public String JavaDoc toString()
332     {
333         if (SanityManager.DEBUG)
334         {
335             return super.toString() +
336                 " Delete :" +
337                 " Slot=" + doMeSlot +
338                 " recordId=" + recordId +
339                 " delete=" + delete;
340         }
341         else
342             return null;
343     }
344 }
345
Popular Tags