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.store.access.conglomerate.LogicalUndo; 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 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.FormatableBitSet; 47 import org.apache.derby.iapi.services.io.CompressedNumber; 48 import org.apache.derby.iapi.util.ByteArray; 49 import org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream; 50 51 import java.io.OutputStream ; 52 import java.io.ObjectOutput ; 53 import java.io.ObjectInput ; 54 import java.io.IOException ; 55 import org.apache.derby.iapi.services.io.LimitObjectInput; 56 57 58 79 public final class UpdateFieldOperation extends LogicalPageOperation 80 { 81 82 protected int doMeSlot; protected int fieldId; 84 85 transient protected ByteArray preparedLog; 86 87 public UpdateFieldOperation( 88 RawTransaction t, 89 BasePage page, 90 int slot, 91 int recordId, 92 int fieldId, 93 Object column, 94 LogicalUndo undo) 95 throws StandardException 96 { 97 super(page, undo, recordId); 98 99 this.doMeSlot = slot; 100 this.fieldId = fieldId; 101 102 try { 103 writeOptionalDataToBuffer(t, column); 104 } catch (IOException ioe) { 105 throw StandardException.newException( 106 SQLState.DATA_UNEXPECTED_EXCEPTION, ioe); 107 } 108 } 109 110 113 114 public UpdateFieldOperation() { super(); } 116 117 public void writeExternal(ObjectOutput out) throws IOException 118 { 119 super.writeExternal(out); 120 CompressedNumber.writeInt(out, doMeSlot); 121 CompressedNumber.writeInt(out, fieldId); 122 } 123 124 129 public void readExternal(ObjectInput in) 130 throws IOException , ClassNotFoundException 131 { 132 super.readExternal(in); 133 doMeSlot = CompressedNumber.readInt(in); 134 fieldId = CompressedNumber.readInt(in); 135 } 136 137 140 public int getTypeFormatId() { 141 return StoredFormatIds.LOGOP_UPDATE_FIELD; 142 } 143 144 147 155 public void doMe(Transaction xact, LogInstant instant, LimitObjectInput in) 156 throws StandardException, IOException 157 { 158 this.page.storeField(instant, doMeSlot, fieldId, in); 159 } 160 161 164 165 173 public void undoMe(Transaction xact, BasePage undoPage, int undoRecordId, 174 LogInstant CLRInstant, LimitObjectInput in) 175 throws StandardException, IOException 176 { 177 int slot = 178 undoPage.findRecordById(undoRecordId, Page.FIRST_SLOT_NUMBER); 179 180 if (SanityManager.DEBUG) 181 { 182 if (undoRecordId != this.recordId) 187 if (undoPage.getPageNumber() == getPageId().getPageNumber()) 188 SanityManager.THROWASSERT( 189 "recordId changed from " + this.recordId + 190 " to " + undoRecordId + 191 " but page number did not change " + 192 undoPage.getPageNumber()); 193 194 if (slot == -1) 195 SanityManager.THROWASSERT( 196 "recordId " + 197 undoRecordId + 198 " not found on page " + 199 undoPage.getPageNumber()); 200 } 201 202 undoPage.skipField((java.io.ObjectInput ) in); undoPage.storeField(CLRInstant, slot, fieldId, in); 204 undoPage.setAuxObject(null); 205 } 206 207 210 211 212 218 public void restoreLoggedRow(Object [] row, LimitObjectInput in) 219 throws StandardException, IOException 220 { 221 BasePage p = null; 222 223 try { 224 p = (BasePage)(getContainer().getPage(getPageId().getPageNumber())); 230 231 p.skipField(in); p.skipField(in); 236 p.restoreRecordFromStream(in, row); 237 238 242 } finally { 243 244 if (p != null) { 245 p.unlatch(); 246 p = null; 247 } 248 } 249 } 250 251 254 255 262 public void restoreMe(Transaction xact, BasePage undoPage, LogInstant CLRInstant, LimitObjectInput in) 263 throws StandardException, IOException 264 { 265 int slot = undoPage.findRecordById(recordId, Page.FIRST_SLOT_NUMBER); 266 if (SanityManager.DEBUG) 267 { 268 if ( ! getPageId().equals(undoPage.getPageId())) 269 SanityManager.THROWASSERT( 270 "restoreMe cannot restore to a different page. " 271 + "doMe page:" + getPageId() + " undoPage:" + 272 undoPage.getPageId()); 273 if (slot != doMeSlot) 274 SanityManager.THROWASSERT( 275 "restoreMe cannot restore to a different slot. " 276 + "doMe slot:" + doMeSlot + " undoMe slot: " + 277 slot + " recordId:" + recordId); 278 } 279 280 undoPage.skipField(in); undoPage.storeField(CLRInstant, slot, fieldId, in); 282 undoPage.setAuxObject(null); 283 } 284 285 290 291 public ByteArray getPreparedLog() 292 { 293 return (this.preparedLog); 294 } 295 296 303 private void writeOptionalDataToBuffer( 304 RawTransaction t, 305 Object column) 306 throws StandardException, IOException 307 { 308 309 if (SanityManager.DEBUG) { 310 SanityManager.ASSERT(this.page != null); 311 } 312 313 DynamicByteArrayOutputStream logBuffer = t.getLogBuffer(); 314 int optionalDataStart = logBuffer.getPosition(); 315 316 if (SanityManager.DEBUG) { 317 SanityManager.ASSERT(optionalDataStart == 0, 318 "Buffer for writing optional data should start at position 0"); 319 } 320 321 this.page.logColumn(doMeSlot, fieldId, column, logBuffer, 100); this.page.logField(doMeSlot, fieldId, logBuffer); if (undo != null) 324 { 325 332 this.page.logRecord(doMeSlot, BasePage.LOG_RECORD_DEFAULT, 333 recordId, (FormatableBitSet) null, logBuffer, 334 (RecordHandle)null); 335 337 } 338 339 int optionalDataLength = logBuffer.getPosition() - optionalDataStart; 340 341 if (SanityManager.DEBUG) { 342 if (optionalDataLength != logBuffer.getUsed()) 343 SanityManager.THROWASSERT("wrong optional data length, optionalDataLength = " 344 + optionalDataLength + ", logBuffer.getUsed() = " + logBuffer.getUsed()); 345 } 346 347 logBuffer.setPosition(optionalDataStart); 349 350 this.preparedLog = new ByteArray(logBuffer.getByteArray(), optionalDataStart, 351 optionalDataLength); 352 } 353 354 357 public String toString() 358 { 359 if (SanityManager.DEBUG) 360 { 361 return super.toString() + 362 "UpdateField : " + 363 " Slot=" + doMeSlot + 364 " recordId=" + recordId + 365 " fieldId=" + fieldId; 366 } 367 else 368 return null; 369 } 370 371 } 372 | Popular Tags |