static RC RollBackInsertion(SM_DbHandle &db, Event &event, RID &rid) { RC rc; printf("QL: Undoing insertion.\n"); // Delete the record. RM_FileHandle *pTableHandle; if ((rc = db.FindTableHandle(event.tableName.c_str(), pTableHandle))) return rc; if ((rc = pTableHandle->DeleteRec(rid))) return rc; // Delete indexes. vector<SM_ActiveAttr> *attrs; if ((rc = db.AllAttributes(event.tableName.c_str(), attrs))) return rc; vector<SM_ActiveAttr>::iterator pActiveAttr; for (pActiveAttr = attrs->begin(); pActiveAttr != attrs->end(); ++pActiveAttr) { if (pActiveAttr->record.hasIndex) { IX_IndexHandle *pIndex = &pActiveAttr->indexHandle; if ((rc = pIndex->DeleteEntry(event.record + pActiveAttr->record.attrOffset, rid))) return rc; } } return 0; }
RC QL_Manager::Delete() { RC rc; vector<RM_Record> chosenRecords; vector<SM_ActiveAttr> *attrs; if ((rc = db.AllAttributes(rmp.relName, attrs))) return rc; RM_FileHandle *pTableHandle; if ((rc = db.FindTableHandle(rmp.relName, pTableHandle))) return rc; if ((rc = FindRecords(rmp.relName, chosenRecords))) return rc; vector<RM_Record>::iterator pRecord; int recordSize = pTableHandle->header.recordSize; for (pRecord = chosenRecords.begin(); pRecord != chosenRecords.end(); ++pRecord) { RID rid; if ((rc = pRecord->GetRid(rid))) return rc; char *data; if ((rc = pRecord->GetData(data))) return rc; Event event; event.type = DELETE; event.record = new char[recordSize]; event.tableName = rmp.relName; memcpy(event.record, data, recordSize); if ((rc = pTableHandle->DeleteRec(rid))) { delete[] event.record; return rc; } // Delete the record from indexes. for (int i = 0; i < attrs->size(); i++) { SM_Attribute *pAttr = &attrs->at(i).record; if (pAttr->hasIndex) { IX_IndexHandle *pIndexHandle = &attrs->at(i).indexHandle; if ((rc = pIndexHandle->DeleteEntry(event.record + pAttr->attrOffset, rid))) return rc; } } map<RID, Event, RID_LessThan>::iterator pPrevEvent = transaction.find(rid); if (pPrevEvent == transaction.end()) { transactionDeleted.push_back(event); } else { if (pPrevEvent->second.type == INSERT) { // Previously inserted. Remove it from the transaction. delete[] event.record; delete[] pPrevEvent->second.record; transaction.erase(pPrevEvent); } else if (pPrevEvent->second.type == UPDATE) { delete[] event.record; pPrevEvent->second.type == DELETE; transactionDeleted.push_back(pPrevEvent->second); transaction.erase(pPrevEvent); } } } return 0; }