static RC RollBackUpdate(SM_DbHandle &db, Event &event, RID &rid) { RC rc; printf("QL: Undoing update.\n"); RM_FileHandle *pTableHandle; if ((rc = db.FindTableHandle(event.tableName.c_str(), pTableHandle))) return rc; RM_Record record; if ((rc = pTableHandle->GetRec(rid, record))) return rc; char *data; if ((rc = record.GetData(data))) return rc; SM_Attribute *pAttr; if ((rc = db.FindAttribute(event.tableName.c_str(), event.attrName.c_str(), pAttr))) return rc; // If indexed, remove the old entry. IX_IndexHandle *pIndexHandle; if (pAttr->hasIndex) { if ((rc = db.FindIndexHandle(event.tableName.c_str(), event.attrName.c_str(), pIndexHandle))) return rc; if ((rc = pIndexHandle->DeleteEntry(data + pAttr->attrOffset, rid))) return rc; } // Restore the record. int recordSize = pTableHandle->header.recordSize; memcpy(data, event.record, recordSize); // Update the record. if ((rc = pTableHandle->UpdateRec(record))) return rc; // If indexed, insert the new entry. if (pAttr->hasIndex) { if ((rc = pIndexHandle->InsertEntry(data + pAttr->attrOffset, rid))) return rc; } return 0; }
RC QL_Manager::FindRecords(const char *relName, vector<RM_Record> &records){ RC rc; RM_FileHandle *rh; IX_IndexHandle *ih; if (rc = db.FindTableHandle(relName, rh)) return rc; RM_FileScan rmscan; IX_IndexScan ixscan; vector<RM_Record> v_now; v_now.clear(); bool flagAll = true; if (rmp.nConditions) { for (int i = 0; i < rmp.nConditions; i++) if (rmp.conditions[i].bRhsIsValue) { if (strcmp(relName, rmp.conditions[i].lhsAttr.relName) != 0) continue; vector<RM_Record> v_tmp; v_tmp.clear(); char *attrName = rmp.conditions[i].lhsAttr.attrName; SM_Attribute *smAttr; if (rc = db.FindAttribute(relName, attrName, smAttr)) return rc; AttrType attrType = smAttr->attrType; int attrLength = smAttr->attrLength; int attrOffset = smAttr->attrOffset; int attrNumber = smAttr->number; CompOp op = rmp.conditions[i].op; void *data = rmp.conditions[i].rhsValue.data; if (smAttr->hasIndex && isCmpOp(op)) { if (rc = db.FindIndexHandle(relName, attrName, ih)) return rc; ixscan.OpenScan(*ih, op, data); RID rid; RM_Record rec; v_tmp.clear(); while (1) { rc = ixscan.GetNextEntry(rid); if (rc != 0 && rc != IX_EOF) return rc; if (rc == IX_EOF) break; if (rc = rh->GetRec(rid, rec)) return rc; v_tmp.push_back(rec); } ixscan.CloseScan(); } else { if (op == IS_OP || op == IS_NOT_OP) { int number = smAttr->number; int nullBitmap = rh->header.recordSize - sizeof(int); if ((rc = rmscan.OpenScan(*rh, NOTYPE, 4, nullBitmap, 0, op, &number))) return rc; } else { if (rc = rmscan.OpenScan(*rh, attrType, attrLength, attrOffset, attrNumber, op, data)) return rc; } v_tmp.clear(); RM_Record rec; while (rmscan.GetNextRec(rec) != RM_ERR_EOF) { v_tmp.push_back(rec); } if (rc = rmscan.CloseScan()) return rc; } if (rc = MergeAnd(v_now, v_tmp, flagAll)) return rc; flagAll = false; } } //cout << "before flagAll\n"; if (flagAll) { int t = 0; if (rc = rmscan.OpenScan(*rh, INT, 4, 0, 0, NO_OP, &t, NO_HINT)) return rc; //cout << "after open scan\n"; RM_Record rec; v_now.clear(); while (rmscan.GetNextRec(rec) != RM_ERR_EOF) v_now.push_back(rec); if (rc = rmscan.CloseScan()) return rc; } //cout << "after flagAll\n"; records.clear(); records.assign(v_now.begin(), v_now.end()); return 0; }