Example #1
0
static RC RollBackDeletion(SM_DbHandle &db, Event &event)
{
    RC rc;
    RID newRid;

    printf("QL: Undoing deletion.\n");

    // Insert the record.
    RM_FileHandle *pTableHandle;
    if ((rc = db.FindTableHandle(event.tableName.c_str(), pTableHandle)))
        return rc;
    if ((rc = pTableHandle->InsertRec(event.record, newRid)))
        return rc;

    // Insert 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->InsertEntry(event.record + pActiveAttr->record.attrOffset, newRid)))
                return rc;
        }
    }

    return 0;
}
Example #2
0
int main(){
    RC rc;
    PF_Manager pfm;
    IX_Manager ixm(pfm);
    IX_IndexHandle ixih;
    IX_IndexScan ixis;

    if(rc=ixm.CreateIndex("indextest",0,FLOAT,4))
        return rc;
    if(rc=ixm.OpenIndex("indextest",0,ixih))
        return rc;
    for(int i=0;i<10;i++){
        Value value((float)i);
        if(rc=ixih.InsertEntry(value,RID(i/10,i%10)))
            return rc;
    }
    if ((rc = ixm.CloseIndex(ixih))) {
        return rc;
    }

    if ((rc=ixm.OpenIndex("indextest",0,ixih))) {
        return rc;
    }
//    for(int i=0;i<1;i++){
//        Value value;
//        value.type=INT;
//        value.iData=i;
//
//        if(rc=ixih.DeleteEntry(value,RID(i/10,i%10)))
//            return rc;
//    }
    ixis.OpenScan(ixih,GE,Value((float)5.0));
    RID id;
    while(ixis.GetNextEntry(id)!=IX_EOF){
        PageNum pageNum;
        SlotNum slotNum;
        id.GetPageNum(pageNum);
        id.GetSlotNum(slotNum);
        cout<<pageNum<<"\t"<<slotNum<<endl;
    }
    if ((rc = ixis.CloseScan())) {
        return rc;
    }
    if ((rc = ixm.CloseIndex(ixih))) {
        return rc;
    }

     return 0;

}
Example #3
0
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;
}
Example #4
0
void test_IX_speed() {
    RID rid;
    IX_Manager manager;
    manager.DestroyIndex("ixtest", 1);
    manager.CreateIndex("ixtest", 1, INTEGER, 8);

    IX_IndexHandle handle;

    long long a;
    printf("begin insert\n");
    for (int i = 1280000; i >= 1; i--) {
    	manager.OpenIndex("ixtest", 1, handle);
        rid.pageid = i; rid.slotid = i;
        a = i;
        if (i % 1000 == 0)
            printf("i = %d \n", i);
        handle.InsertEntry(&a, rid);
        // handle.ForcePages();
        manager.CloseIndex(handle);
    }
    printf("insert finish\n");


    printf("begin delete\n");
    manager.OpenIndex("ixtest", 1, handle);
    for (int i = 60; i >= 56; i--) {
        rid.pageid = i; rid.slotid = i;
        a = i;
        printf("i = %d \n", i);
        handle.DeleteEntry(&a, rid);
        handle.ForcePages();
    }

    for (int i = 1; i <= 30; i++) {
        rid.pageid = i; rid.slotid = i;
        a = i;
        printf("i = %d \n", i);
        handle.DeleteEntry(&a, rid);
        handle.ForcePages();
    }
    rid.pageid = 33; rid.slotid = 33;
    a = 33;
    handle.DeleteEntry(&a, rid);
    printf("delete finish\n");

    IX_IndexScan scan;
    a = 43;
    scan.OpenScan(handle, LE, &a);
    RID scanrid;
    scan.GetNextEntry(scanrid);
    while (scanrid.pageid > 0) {
        printf("rid: %d %d\n", scanrid.pageid, scanrid.slotid);
        scan.GetNextEntry(scanrid);
    }
}
Example #5
0
void Parse_Manager::MainLoop(SM_Manager *smm, RM_Manager *rmm, IX_Manager *ixm) {

	string instruction = string("python python/parser.py ") + filename + string("> tmp");
	system(instruction.c_str());

	fp = fopen("tmp.gen", "r");
	ql_manager = new QL_Manager(smm, rmm, ixm);

	char cmd[256];
	int a = 1;
	while(true) {
		a = 0;
		memset(cmd, 0 , 256);
		fscanf(fp, "%s\n", cmd);
		cout << "cmd: " << cmd << endl;
		if (strcmp(cmd, "Syntax error") == 0)
			cout << "Syntax error" << endl;

		else if(strcmp(cmd, "createdatabase") == 0) { //CREATE DATABASE orderDB;
			char* DBName = readName();
			cout << "CREATE " << DBName<< endl;
			smm->CreateDb(DBName);
		}

		else if(strcmp(cmd, "dropdatabase") == 0) { //DROP DATABASE orderDB;
			char* DBName = readName();
			cout << "DROP " << DBName<< endl;
			smm->DropDb(DBName);
		}

		else if(strcmp(cmd, "use") == 0) { //USE orderDB;
			char* DBName = readName();
			cout << "USE " << DBName<< endl;
			smm->CloseDb();
			smm->OpenDb(DBName);
		}

		else if(strcmp(cmd, "showtables") == 0) { //SHOW TABLES
			cout << "showTables" << endl;
			smm->ShowDb();
		}

		else if(strcmp(cmd, "drop") == 0){ //DROP TABLE customer;
			char* relName = readName();
			cout << relName<< endl;
		}

		else if(strcmp(cmd, "desc") == 0){ //DESC customer;
			char* relName = readName();
			cout << relName<< endl;
		}

		else if(strcmp(cmd, "showtable") == 0){ //SHOW customer
			char* relName = readName();
			cout << relName << endl;
			smm->ShowTable(relName);
		}

		else if(strcmp(cmd, "createtable") == 0){ //CREATE TABLE customer {}
			char* relName = readName();
			cout << relName << endl;
			char* pk = readName();
			cout << pk << endl;
			char *temp = readName();
			if(strcmp(temp, "check") == 0){
				char *check_attr = readName();
				int ntype;
				fscanf(fp, "%d", &ntype);
				cout << check_attr << ' ' << ntype << endl;
				AttrType attrType;
				int attrLength;
				Value* value = new Value[ntype];
				for(int i = 0; i < ntype; i++) {
					fscanf(fp, "%d", &value[i].type);
					if (value[i].type == MyINT){
						readInt(value[i].data);
						attrType = MyINT;
						attrLength = 4;
					}
					else if(value[i].type == FLOAT){
						readFloat(value[i].data);
						attrType = FLOAT;
						attrLength = 4;
					}
					else{
						readString(value[i].data);
						attrType = STRING;
						attrLength = 1024;
					}
					cout << value[i];
				}
				char checkname[512];
				memset(checkname, 0, sizeof checkname);
				sprintf(checkname, "%s.check", check_attr);
				ixm->CreateIndex(relName, checkname, attrType, attrLength);
				IX_IndexHandle ixh;
				ixm->OpenIndex(relName, checkname, ixh);
				for (int i = 0; i < ntype; i++) {
					ixh.InsertEntry(value[i].data, RID(i, 0));
				}
				ixm->CloseIndex(ixh);
			}
			else if(strcmp(temp, "nocheck") == 0) {
				cout << "nocheck" << endl;
			}
			int attrCount;
			AttrInfo* attributes;
			fscanf(fp, "%d", &attrCount);
			attributes = new AttrInfo[attrCount];
			for (int i = 0; i < attrCount; i++){
				memset(attributes[i].attrName, 0, MAXNAME+1);
				fscanf(fp, "%s %d %d %d", attributes[i].attrName, &attributes[i].attrType, &attributes[i].attrLength, &attributes[i].notNull);
				if(strcmp(attributes[i].attrName, pk) == 0) {
					attributes[i].primaryKey = 1;
					ixm->CreateIndex(relName, attributes[i].attrName, attributes[i].attrType, attributes[i].attrLength);
				}
			}
			AttrInfo *x = new AttrInfo[attrCount];
			for (int i = 0; i < attrCount; i++)
				x[i] = attributes[i];
			smm->CreateTable(relName, attrCount, x);
			delete x;
		}

		else if(strcmp(cmd, "createindex") == 0) { //CREATE INDEX customer(name);
			char *relName = readName();
			char *attrName = readName();
			cout << relName << ' ' << attrName << endl;
			int attrNum;
			DataAttrInfo* attrs;
			smm->GetTable(relName, attrNum, attrs);
			for (int i = 0; i < attrNum; i++)
				if (strcmp(attrs[i].attrName, attrName) == 0) {
					//printf("createindex attrName : %s  attrLength : %d  attroffset : %d\n", attrs[i].attrName, attrs[i].attrLength, attrs[i].offset);
					if (ixm->CreateIndex(relName, attrName, attrs[i].attrType, attrs[i].attrLength) == -1)
						break;
					IX_IndexHandle ixh;
					ixm->OpenIndex(relName, attrName, ixh);
					RM_FileHandle relfh;
					rmm->OpenFile(relName, relfh);
					RM_FileScan scan(rmm->getFileManager(), rmm->getBufPageManager());
					scan.OpenScan(relfh, attrs[i].attrType, attrs[i].attrLength, 0, NO_OP, (void*)0);
					int cnt = 0;
					while (true) {
						RM_Record rec;
						if (scan.GetNextRec(rec) == -1)
							break;
						ixh.InsertEntry(rec.data + attrs[i].offset, rec.rid);
						//printf("%d %s  %lld\n", cnt++, rec.data + attrs[i].offset, (long long)(rec.data));
					}
					//printf("\n");
					rmm->CloseFile(relfh);
					ixm->CloseIndex(ixh);
					break;
				}
		}

		else if(strcmp(cmd, "dropindex") == 0) { //DROP INDEX customer(name);
			char *relName = readName();
			char *attrName = readName();
			cout << relName << ' ' << attrName << endl;
			ixm->DestroyIndex(relName, attrName);
		}

		else if(strcmp(cmd, "insert") == 0){
			char* relName = readName();
			int hasAttr;
			fscanf(fp, "%d", &hasAttr);
			AttrInfo* attrs; 
			int nattr = 0;
			if (hasAttr == 1)
				readAttr(nattr, attrs);
			readInsertData(relName, nattr, attrs);
		}

		else if(strcmp(cmd, "delete") == 0){
			char* relName = readName();
			
			char temp[100] = {};
			fscanf(fp, "%s", temp);

			if(strcmp(temp, "where") == 0) {
				int nrid = 0;
				RID *rid;
				readWhere(relName, nrid, rid);
				ql_manager->Delete(relName, nrid, rid);
			}
			else if(strcmp(temp, "enddelete") == 0) {
				ql_manager->Delete(relName, -1, NULL);
			}

			else {
				cout << "Syntax Error" << endl;
				break;
			}
		}

		else if(strcmp(cmd, "update") == 0) {
			char* relName = readName();
			RelAttr l, r;
			Value v;
			int bIsValue = 1;
			
			readRelAttr(l);

			int type;
			fscanf(fp, "%d", &type);
			if (type == 0){
				v.type = MyINT;
				readInt(v.data);
			}
			else if (type == 1){
				v.type = FLOAT;
				readFloat(v.data);
			}
			else if(type == 2){
				v.type = STRING;
				readString(v.data);
			}
			else if(type == 3) {
				bIsValue = 0;
				readRelAttr(r);
			}
			char* ddd = (char*)v.data;

			char temp[100] = {};
			fscanf(fp, "%s", temp);
			if(strcmp(temp, "where") == 0){
				int nrid = 0;
				RID* rid;
				readWhere(relName, nrid, rid);
				ql_manager->Update(relName, l, bIsValue, r, v, nrid, rid);
			}
			else if(strcmp(temp, "endupdate") == 0){
				ql_manager->Update(relName, l, bIsValue, r, v, -1, NULL);
			}
		}

		else if(strcmp(cmd, "select") == 0){
			int nattrs = 0;
			fscanf(fp, "%d", &nattrs);
			RelAttr *attr = new RelAttr[nattrs];
			for(int i = 0; i < nattrs; i++) {
				fscanf(fp, "%d", &attr[i].type);
				readRelAttr(attr[i]);
				//cout << attr[i].type << ' ' << (attr[i].relName == NULL) << ' ' << attr[i].attrName << endl; 
			}
			int nrela = 0;
			fscanf(fp, "%d", &nrela);
cout << nrela << endl;
//			cout << "get 3" << endl;
			//cout << nrela << endl;
			char **rela = new char*[nrela];
			for(int i = 0; i < nrela; i++) {
				rela[i] = new char[MAXNAME];
				memset(rela[i], 0, MAXNAME);
				fscanf(fp, "%s", rela[i]);
				//cout << rela[i] << endl;
			}
			char temp[100] = {};
			fscanf(fp, "%s", temp);
//			cout << "get 4" << endl;
			if(strcmp(temp, "where") == 0) {
				if(nrela == 1) {
					int nrid = 0;
					RID* rid;
					readWhere(rela[0], nrid, rid);
					ql_manager->Print(nattrs, attr, rela[0], nrid, rid);
				}
				else{
					int ncond = 0;
					Condition* cond;
					readWhere(ncond, cond);
//RelAttr gattr;
//ql_manager->Select(0,NULL,0,NULL,0,0,NULL,gattr);
					ql_manager->Select(nattrs, attr, nrela, rela, 0, ncond, cond, attr[0]);
				}
			}
			else if(strcmp(temp, "group") == 0) {
				RelAttr gattr;
				readRelAttr(gattr);
				ql_manager->Select(nattrs, attr, nrela, rela, 1, 0, NULL, gattr);
			}
			else if(strcmp(temp, "endselect") == 0) {
				ql_manager->Select(nattrs, attr, nrela, rela, 0, 0, NULL, attr[0]);
			}
			else{
				cout << "Syntax Error" << endl;
				break;
			}
		}
		else {
			cout << "over" << endl;
			break;
		}
	}
	fclose(fp);
}
Example #6
0
void test_IX() {
    RID rid;
    IX_Manager manager;
    manager.DestroyIndex("ixtest", 0);
    manager.CreateIndex("ixtest", 0, INTEGER, 8);
//
    IX_IndexHandle handle;
    manager.OpenIndex("ixtest", 0, handle);
    char a[480];
    memset(a, 0, 10);
    memset(a + 10, 255, 470);
    printf("begin insert\n");
//    for (int i = 1; i <= 4; i++) {
//        for (int j = 1; j <= 4; j++) {
//            rid.pageid = i; rid.slotid = j;
//            a[i] = j;
//            printf("%d %d\n", i, j);
//            handle.InsertEntry(a, rid);
//            handle.ForcePages();
//        }
//    }
    for (int i = 55; i >= 1; i--) {
        rid.pageid = i; rid.slotid = i;
        a[0] = i;
        printf("i = %d \n", i);
        handle.InsertEntry(a, rid);
        handle.ForcePages();
    }
    printf("insert finish\n");

    printf("begin delete\n");
    for (int i = 60; i >= 56; i--) {
        rid.pageid = i; rid.slotid = i;
        a[0] = i;
        printf("i = %d \n", i);
        handle.DeleteEntry(a, rid);
        handle.ForcePages();
    }

    for (int i = 1; i <= 30; i++) {
        rid.pageid = i; rid.slotid = i;
        a[0] = i;
        printf("i = %d \n", i);
        handle.DeleteEntry(a, rid);
        handle.ForcePages();
    }
    rid.pageid = 33; rid.slotid = 33;
    a[0] = 33;
    handle.DeleteEntry(a, rid);
    printf("delete finish\n");

    IX_IndexScan scan;
    a[0] = 43;
    scan.OpenScan(handle, NE, a);
    RID scanrid;
    scan.GetNextEntry(scanrid);
    while (scanrid.pageid > 0) {
        printf("rid: %d %d\n", scanrid.pageid, scanrid.slotid);
        scan.GetNextEntry(scanrid);
    }

    //    handle.DeleteEntry(&a, rid);
    printf("%d\n", INT_MAX);
}
Example #7
0
RC QL_Manager::Insert()
{
    RC rc;

    const char *tableName = rmp.relName;
    vector<SM_ActiveAttr> *attrs;
    if ((rc = db.AllAttributes(tableName, attrs)))
        return rc;

    if (rmp.nValues != attrs->size()) {
        fprintf(stderr, "QL: Mismatch # of attributes.\n");
        return QL_ERR_INVALID_COMMAND;
    }

    // Fill in the record buffer.
    SM_Attribute *lastAttr = &attrs->at(attrs->size()-1).record;
    int recordSize = lastAttr->attrOffset + lastAttr->attrLength + sizeof(int);

    Event event;
    event.record = new char[recordSize];
    event.type = INSERT;
    event.tableName = rmp.relName;
    memset(event.record, 0, recordSize);

    RM_FileHandle *pTableHandle;
    if ((rc = db.FindTableHandle(rmp.relName, pTableHandle))) {
        delete[] event.record;
        return rc;
    }

    int *pNullBitmap = (int *)(event.record + lastAttr->attrOffset + lastAttr->attrLength);

    for (int i = 0; i < attrs->size(); i++) {
        SM_Attribute *attr = &attrs->at(i).record;
        if (attr->attrType != rmp.values[i].type && rmp.values[i].type != NOTYPE) {
            fprintf(stderr, "QL: Mismatch type for attribute %s\n", attr->attrName);
            delete[] event.record;
            return QL_ERR_INVALID_COMMAND;
        }

        // Check primary key uniqueness.
        if (attr->isPrimary && !attr->hasIndex) {
            RM_FileScan scan;
            if ((rc = scan.OpenScan(*pTableHandle, attr->attrType, 
                                    attr->attrLength, attr->attrOffset,
                                    attr->number,
                                    EQ_OP, rmp.values[i].data)))
                return rc;
            RM_Record rec;
            if (scan.GetNextRec(rec) != RM_ERR_EOF) {
                fprintf(stderr, "QL: Primary key conflicts!\n");
                scan.CloseScan();
                return QL_PRIMARY_KEY;
            }
            if ((rc = scan.CloseScan()))
                return rc;
        }

        // Check foreign key existence.
        if (attr->isForeignKey) {
            RM_FileHandle *pForeign;
            if ((rc = db.FindTableHandle(attr->refTableName, pForeign)))
                return rc;

            SM_Attribute *foreignAttr;
            if ((rc = db.FindAttribute(attr->refTableName, attr->refAttrName, foreignAttr)))
                return rc;

            if (foreignAttr->attrType != attr->attrType) {
                fprintf(stderr, "QL: mismatch attribute type with foreign key.\n");
                return rc;
            }

            RM_FileScan scan;
            if ((rc = scan.OpenScan(*pForeign, foreignAttr->attrType,
                                    foreignAttr->attrLength, foreignAttr->attrOffset,
                                    foreignAttr->number,
                                    EQ_OP, rmp.values[i].data)))
                return rc;

            RM_Record rec;
            if (scan.GetNextRec(rec) != 0) {
                fprintf(stderr, "QL: Foreign key does not exist!\n");
                scan.CloseScan();
                return QL_FOREIGN_KEY;
            }

            if ((rc = scan.CloseScan()))
                return rc;
        }

        if (rmp.values[i].type == NOTYPE) {
            if (attr->hasIndex) {
                fprintf(stderr, "QL: indexed attribute %s cannot be NULL\n", attr->attrName);
                delete[] event.record;
                return QL_ERR_INVALID_COMMAND;
            }
            *pNullBitmap |= 1 << i;
        } else if (rmp.values[i].type == INT || rmp.values[i].type == FLOAT)
            memcpy(event.record + attr->attrOffset, rmp.values[i].data, attr->attrLength);
        else
            strncpy(event.record + attr->attrOffset, (const char *)rmp.values[i].data, attr->attrLength);
    }

    // Insert the record into the database.
    RID rid;
    if ((rc = pTableHandle->InsertRec(event.record, rid))) {
        delete[] event.record;
        return rc;
    }

    transaction.insert(pair<RID, Event>(rid, event));

    // Insert the record into 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;
            //cout << "debug:\n";
            if ((rc = pIndexHandle->InsertEntry(event.record + pAttr->attrOffset, rid)))
                return rc;
        }
    }

    return 0;
}
Example #8
0
RC QL_Manager::Update()
{
    RC rc;
    vector<RM_Record> chosenRecords;

    RM_FileHandle *pTableHandle;
    if ((rc = db.FindTableHandle(rmp.relName, pTableHandle)))
        return rc;

    SM_Attribute *pAttr;
    if ((rc = db.FindAttribute(rmp.relName, rmp.updAttr.attrName, pAttr)))
        return rc;

    if (rmp.rhsValue.type != pAttr->attrType && rmp.rhsValue.type != NOTYPE) {
        fprintf(stderr, "QL: Update attributes with different type!\n");
        return QL_ERR_INVALID_COMMAND;
    }

    if (rmp.rhsValue.type == NOTYPE && pAttr->notNull) {
        fprintf(stderr, "QL: Update not-null attribute with NULL!\n");
        return QL_ERR_INVALID_COMMAND;
    }

    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;
        int *pNullBitmap = (int *)(data + recordSize - sizeof(int));

        // Check primary key uniqueness.
        SM_Attribute *attr = pAttr;
        if (attr->isPrimary && !attr->hasIndex) {
            RM_FileScan scan;
            if ((rc = scan.OpenScan(*pTableHandle, attr->attrType, 
                                    attr->attrLength, attr->attrOffset,
                                    attr->number,
                                    EQ_OP, rmp.rhsValue.data)))
                return rc;
            RM_Record rec;
            if (scan.GetNextRec(rec) != RM_ERR_EOF) {
                fprintf(stderr, "QL: Primary key conflicts!\n");
                scan.CloseScan();
                return QL_PRIMARY_KEY;
            }
            if ((rc = scan.CloseScan()))
                return rc;
        }

        // Check foreign key existence.
        if (attr->isForeignKey) {
            RM_FileHandle *pForeign;
            if ((rc = db.FindTableHandle(attr->refTableName, pForeign)))
                return rc;

            SM_Attribute *foreignAttr;
            if ((rc = db.FindAttribute(attr->refTableName, attr->refAttrName, foreignAttr)))
                return rc;

            if (foreignAttr->attrType != attr->attrType) {
                fprintf(stderr, "QL: mismatch attribute type with foreign key.\n");
                return rc;
            }

            RM_FileScan scan;
            if ((rc = scan.OpenScan(*pForeign, foreignAttr->attrType,
                                    foreignAttr->attrLength, foreignAttr->attrOffset,
                                    foreignAttr->number,
                                    EQ_OP, rmp.rhsValue.data)))
                return rc;

            RM_Record rec;
            if (scan.GetNextRec(rec) != 0) {
                fprintf(stderr, "QL: Foreign key does not exist!\n");
                scan.CloseScan();
                return QL_FOREIGN_KEY;
            }

            if ((rc = scan.CloseScan()))
                return rc;
        }

        Event event;
        event.type = UPDATE;
        event.record = new char[recordSize];
        event.tableName = rmp.relName;
        event.attrName = rmp.updAttr.attrName;
        memcpy(event.record, data, recordSize);

        // If indexed, remove the old entry.
        IX_IndexHandle *pIndexHandle;
        if (pAttr->hasIndex) {
            if ((rc = db.FindIndexHandle(rmp.relName, pAttr->attrName, pIndexHandle))) {
                delete[] event.record;
                return rc;
            }
            if ((rc = pIndexHandle->DeleteEntry(data + pAttr->attrOffset, rid))) {
                delete[] event.record;
                return rc;
            }
        }

        map<RID, Event, RID_LessThan>::iterator pPrevEvent = transaction.find(rid);
        if (pPrevEvent == transaction.end()) {
            transaction.insert(pair<RID, Event>(rid, event));
        } else {
            delete[] event.record;
        }

        // Modify the record.
        if (pAttr->attrType == INT || pAttr->attrType == FLOAT) {
            memcpy(data + pAttr->attrOffset, rmp.rhsValue.data, pAttr->attrLength);
            *pNullBitmap &= ~(1 << pAttr->number);
        } else if (pAttr->attrType == NOTYPE) {
            *pNullBitmap |= 1 << pAttr->number;
        } else {
            strncpy(data + pAttr->attrOffset, (const char *)rmp.rhsValue.data, pAttr->attrLength);
            *pNullBitmap &= ~(1 << pAttr->number);
        }

        // Update the record.
        if ((rc = pTableHandle->UpdateRec(*pRecord))) {
            delete[] event.record;
            return rc;
        }

        // If indexed, insert the new entry.
        if (pAttr->hasIndex) {
            if ((rc = pIndexHandle->InsertEntry(data + pAttr->attrOffset, rid))) {
                delete[] event.record;
                return rc;
            }
        }
        
    }

    return 0;
}
Example #9
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;
}