1 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.impl.store.raw.data.BasePage; 27 28 import org.apache.derby.iapi.services.sanity.SanityManager; 29 30 import org.apache.derby.iapi.services.io.FormatIdUtil; 31 import org.apache.derby.iapi.services.io.StoredFormatIds; 32 33 import org.apache.derby.iapi.error.StandardException; 34 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 39 import org.apache.derby.iapi.store.raw.log.LogInstant; 40 import org.apache.derby.iapi.store.raw.xact.RawTransaction; 41 42 import org.apache.derby.iapi.types.DataValueDescriptor; 43 44 import org.apache.derby.iapi.services.io.FormatableBitSet; 45 import org.apache.derby.iapi.util.ByteArray; 46 import org.apache.derby.iapi.services.io.CompressedNumber; 47 import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream; 48 import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream; 49 50 import java.io.OutputStream ; 51 import java.io.ObjectOutput ; 52 import java.io.ObjectInput ; 53 import java.io.IOException ; 54 import org.apache.derby.iapi.services.io.LimitObjectInput; 55 56 57 76 77 public final class UpdateOperation extends PhysicalPageOperation { 78 79 protected int doMeSlot; protected int recordId; transient protected int nextColumn; 83 transient protected ByteArray preparedLog; 84 85 public UpdateOperation( 86 RawTransaction t, 87 BasePage page, 88 int slot, 89 int recordId, 90 Object [] row, 91 FormatableBitSet validColumns, 92 int realStartColumn, 93 DynamicByteArrayOutputStream logBuffer, 94 int realSpaceOnPage, 95 RecordHandle headRowHandle) 96 throws StandardException 97 { 98 super(page); 99 100 this.doMeSlot = slot; 101 this.recordId = recordId; 102 this.nextColumn = -1; 103 104 try { 106 writeOptionalDataToBuffer(t, (DynamicByteArrayOutputStream) logBuffer, 107 row, validColumns, realStartColumn, 108 realSpaceOnPage, headRowHandle); 109 } catch (IOException ioe) { 110 throw StandardException.newException( 111 SQLState.DATA_UNEXPECTED_EXCEPTION, ioe); 112 } 113 114 } 115 116 119 120 public UpdateOperation() { super(); } 122 123 public void writeExternal(ObjectOutput out) throws IOException 124 { 125 super.writeExternal(out); 126 CompressedNumber.writeInt(out, doMeSlot); 127 CompressedNumber.writeInt(out, recordId); 128 } 129 130 135 public void readExternal(ObjectInput in) 136 throws IOException , ClassNotFoundException 137 { 138 super.readExternal(in); 139 doMeSlot = CompressedNumber.readInt(in); 140 recordId = CompressedNumber.readInt(in); 141 } 142 143 146 public int getTypeFormatId() { 147 return StoredFormatIds.LOGOP_UPDATE; 148 } 149 150 153 public int getNextStartColumn() { 154 return nextColumn; 155 } 156 157 160 170 public void doMe(Transaction xact, LogInstant instant, LimitObjectInput in) 171 throws StandardException, IOException 172 { 173 this.page.storeRecord(instant, doMeSlot, false, in); 174 } 175 176 177 180 181 191 public void undoMe(Transaction xact, BasePage undoPage, 192 LogInstant CLRInstant, LimitObjectInput in) 193 throws StandardException, IOException 194 { 195 196 int slot = undoPage.findRecordById(recordId, Page.FIRST_SLOT_NUMBER); 197 198 undoPage.skipRecord(in); 200 201 undoPage.storeRecord(CLRInstant, slot, false, in); 202 undoPage.setAuxObject(null); 203 } 204 205 210 211 public ByteArray getPreparedLog() 212 { 213 return (this.preparedLog); 214 } 215 216 223 private void writeOptionalDataToBuffer( 224 RawTransaction t, 225 DynamicByteArrayOutputStream logBuffer, 226 Object [] row, 227 FormatableBitSet validColumns, 228 int realStartColumn, 229 int realSpaceOnPage, 230 RecordHandle headRowHandle) 231 throws StandardException, IOException 232 { 233 234 if (SanityManager.DEBUG) 235 { 236 SanityManager.ASSERT(this.page != null); 237 } 238 239 if (realStartColumn == (-1)) 240 { 241 logBuffer = t.getLogBuffer(); 242 } 243 244 int optionalDataStart = logBuffer.getPosition(); 245 246 if (SanityManager.DEBUG) 247 { 248 249 SanityManager.ASSERT( 250 (realStartColumn != -1 || optionalDataStart == 0), 251 "Buffer for writing optional data should start at position 0"); 252 } 253 254 255 this.nextColumn = 256 this.page.logRow( 257 doMeSlot, false, recordId, row, validColumns, 258 logBuffer, 0, Page.INSERT_OVERFLOW, realStartColumn, 259 realSpaceOnPage, 100); 260 261 FormatableBitSet loggedColumns = validColumns; 262 263 268 if ((nextColumn != -1) && (validColumns != null)) 269 { 270 274 int numberFields = page.getHeaderAtSlot(doMeSlot).getNumberFields(); 276 277 loggedColumns = new FormatableBitSet(validColumns); 279 280 int endField = nextColumn + numberFields; 286 loggedColumns.grow(endField); 287 for (int i = nextColumn; i < endField; i++) 291 { 292 loggedColumns.set(i); 293 } 294 } 295 296 this.page.logRecord( 298 doMeSlot, BasePage.LOG_RECORD_FOR_UPDATE, 299 recordId, loggedColumns, logBuffer, headRowHandle); 300 301 optionalDataStart = logBuffer.getBeginPosition(); 303 int optionalDataLength = logBuffer.getPosition() - optionalDataStart; 304 305 logBuffer.setPosition(optionalDataStart); 307 308 this.preparedLog = new ByteArray( 309 logBuffer.getByteArray(), optionalDataStart, optionalDataLength); 310 } 311 312 315 316 323 public void restoreMe(Transaction xact, BasePage undoPage, 324 LogInstant CLRInstant, LimitObjectInput in) 325 throws StandardException, IOException 326 { 327 undoMe(xact, undoPage, CLRInstant, in); 328 } 329 330 331 public String toString() 332 { 333 if (SanityManager.DEBUG) 334 { 335 return super.toString() + 336 "Update " + 337 " Slot=" + doMeSlot + 338 " recordId=" + recordId; 339 } 340 else 341 return null; 342 } 343 } 344 | Popular Tags |