예제 #1
0
int SM_Manager::ShowTable (const char *readRelName){
	//打开attr文件,查询所有relName属性 = readRelName的记录, 打印该记录
	RM_FileScan rfs = RM_FileScan(rmm.getFileManager(), rmm.getBufPageManager());	
 	RM_Record rec;
	int returnCode;
//	cout << "ShowTable" << endl;
	rmm.OpenFile("attrcat", attrfh);
	returnCode = rfs.OpenScan(attrfh, STRING, strlen(readRelName), 16, EQ_OP, (void*)readRelName);
	int x = 0;
//	cout << "TableName : "<< readRelName << endl;
//	cout << "returnCode: " << returnCode << endl;
	while (returnCode == 1){
//		cout << "ret : 1" << endl;
		x = rfs.GetNextRec(rec);
//		cout << "ret : 2" << endl;
		if (x == -1)
			break;
		cout << x << endl;
		DataAttrInfo * mydata;
		rec.GetData((char*&) mydata);
		mydata->print();
	}
	cout << "Table End" << endl;
	rfs.CloseScan();
	rmm.CloseFile(attrfh);
	return 0;
}
예제 #2
0
int SM_Manager::GetTable (const char *readRelName, int &number, DataAttrInfo* &dataInfo){
	//打开attr文件,查询所有relName属性 = readRelName的记录, 将attr个数传给number, dataAttrInfo传给dataInfo,内存释放需要外面执行
	//属性个数存在上限100
	RM_FileScan rfs = RM_FileScan(rmm.getFileManager(), rmm.getBufPageManager());	
 	RM_Record rec;
	int returnCode;
//	cout << "GetTable" << endl;
	rmm.OpenFile("attrcat", attrfh);
	returnCode = rfs.OpenScan(attrfh, STRING, strlen(readRelName), 16, EQ_OP, (void*)readRelName);
	int x = 0;
	dataInfo = new DataAttrInfo[100];
	number = 0;
//	cout << "TableName : "<< readRelName << endl;
	while (returnCode == 1){
//		cout << "ret : 1" << endl;
		x = rfs.GetNextRec(rec);
//		cout << "ret : 2" << endl;
		if (x == -1)
			break;
//		cout << x << endl;
		DataAttrInfo * mydata;
		rec.GetData((char*&) mydata);
		dataInfo[number].copy(mydata);
		number++;
	}
//	cout << "Table End" << endl;
	rfs.CloseScan();
	rmm.CloseFile(attrfh);
	return 0;
}
예제 #3
0
int SM_Manager::ShowDb() {
	CloseDb();
	if (OpenDb(DataName) != 0)
		return -1;
	rmm.OpenFile("tablelist", tablefh);
	RM_FileScan rfs = RM_FileScan(rmm.getFileManager(), rmm.getBufPageManager());
	 RM_Record rec;
	rfs.OpenScan(tablefh, STRING, 0, 0, NO_OP, NULL);
	cout << "----- begin -----" << endl;
	while (rfs.GetNextRec(rec) != -1) {
		cout << rec.rid << " , " << rec.data << endl;
	}
	cout << "----- end -----" << endl;
	rmm.CloseFile(tablefh);
	return 0;
}
예제 #4
0
int SM_Manager::DropTable (const char * deleteRelName){
	RM_FileScan rfs = RM_FileScan(rmm.getFileManager(), rmm.getBufPageManager());
	RM_Record rec;
	//RM_FileHandle attrfh;
	//RM_FileHandle relfh;
	//打开rel文件,查询所有relName属性 = deleteRelName的记录,删除该记录
/*	rfs.OpenScan(relfh, STRING, strlen(deleteRelName), 4, EQ_OP, (void*)deleteRelName);
	while (rfs.GetNextRec(rec) != -1){
		relfh.DeleteRec(rec.rid);
	}
	rfs.CloseScan();*/
	//打开attr文件,查询所有relName属性 = deleteRelName的记录,删除该记录
	rmm.OpenFile("attrcat", attrfh);
	rfs.OpenScan(attrfh, STRING, strlen(deleteRelName), 16, EQ_OP, (void*)deleteRelName);
	while (rfs.GetNextRec(rec) != -1){
		attrfh.DeleteRec(rec.rid);
	}
	rfs.CloseScan();
	rmm.CloseFile(attrfh);
	rmm.OpenFile("tablelist", tablefh);
	rfs.OpenScan(tablefh, STRING, strlen(deleteRelName), 0, EQ_OP, (void*)deleteRelName);
	if (rfs.GetNextRec(rec) != -1){
		tablefh.DeleteRec(rec.rid);
	}
	rfs.CloseScan();
	rmm.CloseFile(tablefh);
	rmm.DestroyFile(deleteRelName);
	return 0;
}
예제 #5
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;
}
예제 #6
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;
}
예제 #7
0
static RC PrintTable(SM_DbHandle &db, const char *tableName)
{
    RC rc;

    RM_FileHandle *pTable;
    if ((rc = db.FindTableHandle(tableName, pTable)))
        return rc;
    int recordSize = pTable->header.recordSize;

    vector<SM_ActiveAttr> *attributes;
    if ((rc = db.AllAttributes(tableName, attributes)))
        return rc;

    RM_FileScan allScan;
    if ((rc = allScan.OpenScan(*pTable, INT, 0, 0, 0, NO_OP, NULL)))
        return rc;
    RM_Record record;
    int recordCount = 0;

    printf("Table: %s\n", tableName);
    while ((rc = allScan.GetNextRec(record)) == 0) {
        RID rid;
        if ((rc = record.GetRid(rid)))
            return rc;
        PageNum pageNum;
        int slotNum;
        if ((rc = rid.GetPageNum(pageNum)))
            return rc;
        if ((rc = rid.GetSlotNum(slotNum)))
            return rc;

        char *data;
        if ((rc = record.GetData(data)))
            return rc;

        printf("RID: (%d,%d)\n", pageNum, slotNum);
        vector<SM_ActiveAttr>::iterator pAttr;

        int *pNullBitmap = (int *)(data + recordSize - sizeof(int));
        for (pAttr = attributes->begin(); pAttr != attributes->end(); ++pAttr) {
            SM_Attribute *attr = &pAttr->record;
            if (*pNullBitmap & (1 << attr->number))
                printf("  %s: Null\n", attr->attrName);
            else if (attr->attrType == INT)
                printf("  %s: %d\n", attr->attrName, *(int *)(data + attr->attrOffset));
            else if (attr->attrType == FLOAT)
                printf("  %s: %f\n", attr->attrName, *(float *)(data + attr->attrOffset));
            else if (attr->attrType == STRING)
                printf("  %s: %s\n", attr->attrName, data + attr->attrOffset);
        }
        printf("\n");
        recordCount++;
    }
    if (rc != RM_ERR_EOF)
        return rc;
    if ((rc = allScan.CloseScan()))
        return rc;
        printf("\nTotal %d records.\n", recordCount);

    return 0;
}
예제 #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;
}