const Status RelCatalog::help(const string & relation) { Status s; RelDesc rd; AttrDesc *attrs; int attrCnt; RID rid; Record rec; if (relation.empty()) return UT_Print(RELCATNAME); /** my code starts here **/ // check if relation exists s = relCat->getInfo(relation, rd); if(s != OK){ return RELNOTFOUND; } HeapFileScan* hfs = new HeapFileScan(RELCATNAME, s); CHKSTAT(s); s = hfs->startScan(0, MAXNAME, STRING, relation.c_str(), EQ); s = hfs->scanNext(rid); CHKSTAT(s); s = hfs->getRecord(rec); CHKSTAT(s); memcpy((void*)&rd, rec.data, rec.length); printf("Relation name: %s, (%d Attributes)\n", rd.relName, rd.attrCnt); printf("==========================================\n"); printf("Attribute Name\tOffset\tType\tLength\n"); delete hfs; hfs = new HeapFileScan(ATTRCATNAME, s); CHKSTAT(s); s = hfs->startScan(0, MAXNAME, STRING, relation.c_str(), EQ); CHKSTAT(s); attrs = new AttrDesc[rd.attrCnt]; for(int i = 0; i < rd.attrCnt; i++){ s = hfs->scanNext(rid); CHKSTAT(s); s = hfs->getRecord(rec); CHKSTAT(s); memcpy(attrs+i, rec.data, rec.length); } for(int i = 0; i < rd.attrCnt; i++){ printf("%s\t\t%d\t%d\t%d\n", attrs[i].attrName, attrs[i].attrOffset, attrs[i].attrType, attrs[i].attrLen); } delete[] attrs; attrs = NULL; delete hfs; hfs = NULL; return OK; }
const Status RelCatalog::removeInfo(const string & relation) { Status status = OK; RID rid; HeapFileScan* hfs; if (relation.empty()) return BADCATPARM; while (status == OK) { hfs = new HeapFileScan(RELCATNAME, status); // you have to start a filter scan on relcat to locate the rid of the desired tuple. status = hfs->startScan(0, relation.length() + 1, STRING, relation.c_str(), EQ); status = hfs->scanNext(rid); // delete the record status = hfs->deleteRecord(); break; } if (status == NORECORDS) { return OK; } else if (status == FILEEOF) { return RELNOTFOUND; } else { return status; } }
// // Remove the tuple corresponding to relName from relcat. It performs the following steps: // // start a filter scan on relcat to locate the rid of the desired tuple // call deleteRecord() to remove the tuple // // Returns: // OK on success // error code otherwise // const Status RelCatalog::removeInfo(const string & relation) { Status status; RID rid; HeapFileScan* hfs; if (relation.empty()) return BADCATPARM; //create a new file scan hfs=new HeapFileScan(RELCATNAME, status); if (status!=OK) return status; const char * relation_name_ptr = relation.c_str(); // open startScan, use the predicate to find matching record status=hfs->startScan(0, MAXNAME, STRING, relation_name_ptr, EQ); if (status!=OK) return status; Record rec; // scan through relation catalog // assume there is no duplicate while ((status = hfs->scanNext(rid)) != FILEEOF){ // get record status = hfs->getRecord(rec); if (status!=OK) return status; //delete current record hfs->deleteRecord(); delete hfs; return OK; } return RELNOTFOUND; }
const Status RelCatalog::getInfo(const string & relation, RelDesc &record) { Status status = OK; Record rec; RID rid; //heapfile scan if (relation.empty()) return BADCATPARM; while (status == OK) { // Open a scan on the relcat relation by invoking the startScan() method on itself. HeapFileScan* hfs = new HeapFileScan(RELCATNAME, status); status = hfs->startScan(0, relation.length() + 1, STRING, relation.c_str(), EQ); // You want to look for the tuple whose first attribute matches the string relName. // Then call scanNext() and getRecord() to get the desired tuple. status = hfs->scanNext(rid); status = hfs->getRecord(rec); // Finally, you need to memcpy() the tuple out of the buffer pool into the return parameter record. memcpy((void*)&record, rec.data, rec.length); return status; } if (status == FILEEOF) { return RELNOTFOUND; } return status; }
const Status RelCatalog::removeInfo(const string & relation) { Status status; RID rid; HeapFileScan* hfs; if (relation.empty()) return BADCATPARM; hfs = new HeapFileScan(RELCATNAME,status); if (status != OK) return status; hfs->startScan(0,relation.length(),STRING,relation.c_str(),EQ); if (status != OK) return status; status=hfs->scanNext(rid); if (status != OK) return status; status = hfs->deleteRecord(); if (status != OK) return status; hfs->endScan(); delete hfs; return OK; }
const Status AttrCatalog::removeInfo(const string & relation, const string & attrName) { Status status; Record rec; RID rid; AttrDesc record; HeapFileScan* hfs; if (relation.empty() || attrName.empty()) return BADCATPARM; hfs = new HeapFileScan(ATTRCATNAME,status); if (status != OK) return status; hfs->startScan(0,sizeof(record.relName),STRING,relation.c_str(),EQ); if (status != OK) return status; while ((status=hfs->scanNext(rid)) != FILEEOF) { if (status != OK) return status; status=hfs->getRecord(rec); if (status != OK) return status; if (strncmp((char*)rec.data + sizeof(record.relName),attrName.c_str(),sizeof(record.attrName))==0) { status = hfs->deleteRecord(); if (status != OK) return status; break; } } hfs->endScan(); delete hfs; return OK; }
const Status AttrCatalog::getInfo(const string & relation, const string & attrName, AttrDesc &record) { Status status; RID rid; Record rec; HeapFileScan* hfs; hfs = new HeapFileScan(ATTRCATNAME,status); if (status != OK) return status; hfs->startScan(0,sizeof(record.relName),STRING,relation.c_str(),EQ); if (status != OK) return status; while ((status=hfs->scanNext(rid)) != FILEEOF) { if (status != OK) return status; status=hfs->getRecord(rec); if (status != OK) return status; if (strncmp((char*)rec.data + sizeof(record.relName),attrName.c_str(),sizeof(record.attrName))==0) { memcpy(&record,rec.data,rec.length); break; } } hfs->endScan(); delete hfs; return OK; }
const Status RelCatalog::getInfo(const string & relation, RelDesc &record) { if (relation.empty()) return BADCATPARM; Status status; Record rec; RID rid; HeapFileScan * scan; scan = new HeapFileScan(RELCATNAME,status); if (status != OK) return status; scan->startScan(0,sizeof(record.relName),STRING,relation.c_str(),EQ); if (status != OK) return status; status=scan->scanNext(rid); if (status == FILEEOF) return RELNOTFOUND; if ((status != FILEEOF) && (status != OK)) return status; status=scan->getRecord(rec); if (status != OK) return status; memcpy(&record,rec.data,rec.length); scan->endScan(); delete scan; scan = NULL; return OK; }
const Status QU_Delete(const string & relation, const string & attrName, const Operator op, const Datatype type, const char *attrValue) { Status status; Status ScanStatus = OK; RID rid; AttrDesc *ad; int attrCnt; HeapFileScan *hfs = new HeapFileScan(relation,status); if(status != OK) {delete(hfs); return status;} status = attrCat->getRelInfo(relation, attrCnt, ad); if(status != OK) {delete(hfs); return status;} // Find out the attribute's size int attrSize; int attrOffset; for(int i = 0; i < attrCnt; i++) if(strcmp(ad[i].attrName,attrName.c_str()) == 0) { attrSize = ad[i].attrLen; attrOffset = ad[i].attrOffset; } // Start a scan (* DO WE NEED TO CAST ATTRVALUE??) status = hfs->startScan(attrOffset,attrSize,type,attrValue,op); if(status != OK) {delete(hfs); return status;} // Find and delete all matching records ScanStatus = hfs->scanNext(rid); while(ScanStatus != FILEEOF){ status = hfs->deleteRecord(); if(status != OK) {delete(hfs); return status;} ScanStatus = hfs->scanNext(rid); if(ScanStatus == FILEEOF) {delete(hfs); return OK; } } // Done delete(hfs); return ScanStatus; }
const Status AttrCatalog::getRelInfo(const string & relation, int &attrCnt, AttrDesc *&attrs) { Status status = OK; RID rid; Record rec; HeapFileScan* hfs; hfs = new HeapFileScan(ATTRCATNAME, status); if (relation.empty()) return BADCATPARM; // status = relCat->getInfo(relation,description); // if (status != OK) { // return status; // } // attrCnt = description.attrCnt; // attrs = new AttrDesc[attrCnt]; while (status == OK) { status = hfs->startScan(0, relation.length() + 1, STRING, relation.c_str(), EQ); attrCnt = 0; while (hfs->scanNext(rid) != FILEEOF) { status = hfs->getRecord(rec); attrCnt = attrCnt + 1; // First run through, create attrs. if (attrCnt == 1) { attrs = (AttrDesc*)(malloc(sizeof(AttrDesc))); } // Expand attrs else { attrs = (AttrDesc*)(realloc(attrs, attrCnt * sizeof(AttrDesc))); } memcpy(&attrs[attrCnt - 1], rec.data, rec.length); } break; } if (status == FILEEOF) { status = OK; } // else if (attrCnt == 0) // { // return RELNOTFOUND; // } else { return status; } }
const Status QU_Delete(const string & relation, const string & attrName, const Operator op, const Datatype type, const char *attrValue) { Status status; HeapFileScan *hfs; AttrDesc record; RID rid; int tempInt; float tempFloat; hfs = new HeapFileScan(relation, status); //Get the AttrDesc from the attrCat table if (attrValue != NULL){ status = attrCat->getInfo(relation, attrName, record); if (status != OK) return status; } //check type and cast accordingly if(type == INTEGER){ tempInt = atoi(attrValue); attrValue = (char *) &tempInt; } else if(type == FLOAT){ tempFloat = atof(attrValue); attrValue = (char *) &tempFloat; } //Start HFS on the relation table status = hfs->startScan(record.attrOffset, record.attrLen, type, attrValue, op); if(status != OK) return status; while((status = hfs->scanNext(rid)) != FILEEOF){ if(status != OK) return status; //Delete record if found in relation table status = hfs->deleteRecord(); if(status != OK) return status; } //If end of file then return attribute not found if (status == FILEEOF){ status = OK; } delete hfs; return status; }
// // Gets descriptors for all attributes of the relation via attr, an array of AttrDesc structures // and the count of the number of attributes in attrCnt // // Returns: // OK on success // error code otherwise // const Status AttrCatalog::getRelInfo(const string & relation, int &attrCnt, AttrDesc *&attrs) { Status status; RID rid; Record rec; HeapFileScan* hfs; if (relation.empty()) return BADCATPARM; RelDesc relRec; if((status = relCat->getInfo(relation,relRec)) != OK) return status; attrs = new AttrDesc[relRec.attrCnt]; int i = 0; hfs = new HeapFileScan(ATTRCATNAME,status); if(status != OK) return status; const char* rel_name_ptr = relation.c_str(); status = hfs->startScan(0,MAXNAME,STRING, rel_name_ptr,EQ); if(status != OK){ delete hfs; return status; } while((status = hfs->scanNext(rid)) != FILEEOF){ status = hfs->getRecord(rec); if(status != OK){ delete hfs; return status; } memcpy(&attrs[i],rec.data,sizeof(AttrDesc)); i++; } delete hfs; if(i != relRec.attrCnt) return ATTRNOTFOUND; else{ attrCnt = relRec.attrCnt; return OK; } }
const Status AttrCatalog::removeInfo(const string & relation, const string & attrName) { Status status = OK; Record rec; RID rid; AttrDesc record; HeapFileScan* hfs; if (relation.empty() || attrName.empty()) return BADCATPARM; while (status == OK) { hfs = new HeapFileScan(ATTRCATNAME, status); // you have to start a filter scan on relcat to locate the rid of the desired tuple. status = hfs->startScan(0, relation.length() + 1, STRING, relation.c_str(), EQ); while (hfs->scanNext(rid) != FILEEOF) { status = hfs->getRecord(rec); memcpy(&record, rec.data, rec.length); if (strcmp(record.attrName, attrName.c_str()) == 0) { // Then you can call deleteRecord() to remove it status = hfs->deleteRecord(); // break instead? return status; } } break; } if (status == FILEEOF) { return status; } else if (status == NORECORDS) { return OK; } else { return status; } }
// // Removes the tuple from attrcat that corresponds to attribute attrName of relation. // // Returns: // OK on success // error code otherwise // const Status AttrCatalog::removeInfo(const string & relation, const string & attrName) { Status status; Record rec; RID rid; HeapFileScan* hfs; if (relation.empty() || attrName.empty()) return BADCATPARM; hfs = new HeapFileScan(ATTRCATNAME,status); if(status != OK) return status; const char* rel_name_ptr = relation.c_str(); const char* attr_name_ptr = attrName.c_str(); status = hfs->startScan(0,MAXNAME,STRING,rel_name_ptr,EQ); if(status != OK){ delete hfs; return status; } //first search all the attribute correspond to the relation while((status = hfs->scanNext(rid)) != FILEEOF){ status = hfs->getRecord(rec); if(status != OK){ delete hfs; return status; } //find the attribute if(memcmp(attr_name_ptr,((AttrDesc *)rec.data)->attrName,attrName.length() ) == 0){ //attribute found and detele hfs->deleteRecord(); delete hfs; //decrease the relation attrCnt return OK; } } delete hfs; return ATTRNOTFOUND; }
// // Gets the attribute descriptor record for attribute attrName in relation relName. It performs the following steps: // // uses a scan over the underlying heapfile to get all tuples for relation // check each tuple to find whether it corresponds to attrName. // // Returns: // OK on success // error code otherwise // const Status AttrCatalog::getInfo(const string & relation, const string & attrName, AttrDesc & record) { Status status; RID rid; Record rec; HeapFileScan* hfs; if (relation.empty() || attrName.empty()) return BADCATPARM; hfs = new HeapFileScan(ATTRCATNAME, status); if(status != OK) return status; const char* rel_name_ptr = relation.c_str(); const char* attr_name_ptr = attrName.c_str(); status = hfs->startScan(0,MAXNAME,STRING,rel_name_ptr,EQ); if(status != OK){ delete hfs; return status; } while( (status = hfs->scanNext(rid)) != FILEEOF){ status = hfs->getRecord(rec); if(status != OK){ delete hfs; return status; } if(memcmp(attr_name_ptr,((AttrDesc *)rec.data)->attrName,attrName.length()) == 0){ memcpy(&record,rec.data,sizeof(AttrDesc)); delete hfs; return OK; } } delete hfs; return ATTRNOTFOUND; }
const Status AttrCatalog::getRelInfo(const string & relation, int &attrCnt, AttrDesc *&attrs) { Status status; RID rid; Record rec; HeapFileScan* hfs; RelDesc rel; if (relation.empty()) return BADCATPARM; status = relCat->getInfo(relation, rel); //if (status == FILEEOF) return RELNOTFOUND; //if ((status != FILEEOF) && (status != OK)) return status; if (status != OK) return status; hfs = new HeapFileScan(ATTRCATNAME,status); hfs->startScan(0,sizeof(attrs->relName),STRING,relation.c_str(),EQ); if (status != OK) return status; attrCnt = 0; attrs = new AttrDesc[10]; while ((status=hfs->scanNext(rid)) != FILEEOF) { if (status != OK) return status; status=hfs->getRecord(rec); if (status != OK) return status; memcpy(&attrs[attrCnt],rec.data,rec.length); attrCnt++; } hfs->endScan(); delete hfs; return OK; }
// Returns the attribute descriptor record for attribute attrName in relation relName. const Status AttrCatalog::getInfo(const string & relation, const string & attrName, AttrDesc &record) { Status status = OK; RID rid; Record rec; HeapFileScan* hfs; hfs = new HeapFileScan(ATTRCATNAME, status); if (relation.empty() || attrName.empty()) return BADCATPARM; // Uses a scan over the underlying heapfile to get all tuples for relation // and check each tuple to find whether it corresponds to attrName. while (status == OK) { status = hfs->startScan(0, relation.length() + 1, STRING, relation.c_str(), EQ); while (hfs->scanNext(rid) != FILEEOF) { status = hfs->getRecord(rec); memcpy(&record, rec.data, rec.length); if (strcmp(record.attrName, attrName.c_str()) == 0) { // Break here? return status; } } break; } if (status == FILEEOF) { return ATTRNOTFOUND; } return status; }
const Status QU_Update(const string & relation, const int attrCnt, const attrInfo attrList[], const string & attrName, const Operator op, const Datatype type, const char *attrValue) { //typedef struct { // char relName[MAXNAME]; // relation name // char attrName[MAXNAME]; // attribute name // int attrOffset; // attribute offset // int attrType; // attribute type // int attrLen; // attribute length //} AttrDesc; // typedef struct { // char relName[MAXNAME]; // relation name // char attrName[MAXNAME]; // attribute name // int attrType; // INTEGER, FLOAT, or STRING // int attrLen; // length of attribute in bytes // void *attrValue; // ptr to binary value //} attrInfo; Status status; HeapFileScan *hfs; InsertFileScan *ifs; AttrDesc rd,temp[attrCnt]; int tempi,tempa; float tempf,tempb; RID rid,Rid; Record rec,recd; int i=0; if (relation.empty()) return BADCATPARM; ifs=new InsertFileScan(relation,status); if(status!=OK) return status; hfs=new HeapFileScan(relation,status); if(status!=OK) return status; // cout<< "------------attrCnt "<< attrCnt<<endl; // cout<<" ------------- relation "<< relation<<endl; // for(int i=0;i<attrCnt;i++) // { // cout<<i<<" "<<" attrList->relName "<< attrList[i].relName<<endl; // cout<<i<<" "<<" attrList->attrName "<< attrList[i].attrName<<endl; // cout<<i<<" "<<"attrList->attrType "<< attrList[i].attrType<<endl; // cout<<i<<" "<<"attrList->attrLen "<< attrList[i].attrLen<<endl; // cout<<i<<" "<<"attrList-attrValue "<< attrList[i].attrValue<<endl; // } // cout<<" ------------ attrName "<< attrName<<endl; // if((status=QU_Insert(relation, attrCnt, attrList))!=OK) // return status; // if((status=QU_Delete(relation, attrName, op, type, attrValue))!=OK) // return status; if((status=attrCat->getInfo(relation, attrName,rd))!=OK) return status; cout<<" "<<" rd.relName "<< rd.relName<<endl; cout<<" "<<" rd.attrName "<< rd.attrName<<endl; cout<<" "<<"rd.attrType "<< rd.attrType<<endl; cout<<" "<<"rd.attrLen " << rd.attrLen<<endl; cout<<" "<<"ard.attrOffset "<< rd.attrOffset<<endl; switch(rd.attrType) { case INTEGER: tempi=atoi(attrValue); if((status=hfs->startScan(rd. attrOffset,rd. attrLen, INTEGER, (char*)&tempi,op))!=OK) return OK; break; case FLOAT: tempf=atof(attrValue); if(( status=hfs->startScan(rd. attrOffset ,rd. attrLen ,FLOAT,(char*)&tempf,op))!=OK) return status; break; default: if(( status=hfs->startScan(rd. attrOffset,rd. attrLen ,STRING,(char*)attrValue,op))!=OK) return status; break; } while ((status=hfs->scanNext(rid)) != FILEEOF) { i=i+1; if((status=hfs->getRecord(rec))!=OK) return status; char data[rec.length]; memcpy(&data, rec.data,rec.length ); if((status=hfs-> deleteRecord())!=OK) return status; // cout<<"---------------"<<rec.length<<endl; for(int j=0;j<attrCnt;j++) { if((status=attrCat->getInfo(attrList[j].relName, attrList[j].attrName,temp[j]))!=OK) return status; // switch(temp[j].attrType) // { // case INTEGER: // tempa=atoi((char *)attrList[j].attrValue); // memcpy(&data[ temp[j].attrOffset], &tempa,temp[j]. attrLen ); 覆盖数据 // return OK; // break; // case FLOAT: // tempb=atof((char *)attrList[j].attrValue); // memcpy(&data[ temp[j].attrOffset], &tempb,temp[j]. attrLen ); 覆盖数据 // break; // default: // memcpy(&data[ temp[j].attrOffset],(char *)attrList[j].attrValue,temp[j]. attrLen ); 覆盖数据 // break; // memcpy(&data[ temp[j].attrOffset],(char *)attrList[j].attrValue,temp[j]. attrLen ); //覆盖数据 } // recd.data=data; // recd.length=rec.length; // cout<<"1111111111111111"<<endl; // if((status=ifs->insertRecord(recd, Rid))!=OK) // return status; } // cout<<" 总共找到的个数 -------------- "<<i<<endl; delete hfs; delete ifs; return OK; }
/** * FUNCTION: ScanSelect * * PURPOSE: Selects records from the specified relation. * * PARAMETERS: * result (out) Relation name where result is to be stored * projCnt (in) Count of projections * projNames_Descs (in) Attribute description array of projections * filterAttr (in) Attribute description of the attribute to be matched * op (in) Operator to be used for matching * filterValue (in) Value to be used for matching * reclen (in) Length of the filter value * * RETURN VALUES: * Status OK Selected records successfully found and returned * BADCATPARM Relation name is empty * BADSCANPARM Error in allocating page: All buffer frames are pinned * FILEEOF Reached the end of file while scanning for the record * BUFFEREXCEEDED All buffer frames are pinned * HASHTBLERROR Hash table error occurred * PAGENOTPINNED Pin count is already 0 * HASHNOTFOUND Page is not in the buffer pool hash table **/ const Status ScanSelect(const string & result, const int projCnt, const AttrDesc projNames_Descs[], const AttrDesc *filterAttr, const Operator op, const char *filterValue, const int reclen) { cout << "Doing HeapFileScan Selection using ScanSelect()" << endl; Record rec; RID rid; Status status; HeapFileScan* hfs = new HeapFileScan(projNames_Descs[0].relName, status); if (status != OK) { delete hfs; return status; } if(filterAttr == NULL) { if ((status = hfs->startScan(0, 0, STRING, NULL, EQ)) != OK) { delete hfs; return status; } } else { int intValue; float floatValue; switch(filterAttr->attrType) { case STRING: status = hfs->startScan(filterAttr->attrOffset, filterAttr->attrLen, (Datatype) filterAttr->attrType, filterValue, (Operator) op); break; case INTEGER: intValue = atoi(filterValue); status = hfs->startScan(filterAttr->attrOffset, filterAttr->attrLen, (Datatype) filterAttr->attrType, (char *)&intValue, (Operator) op); break; case FLOAT: floatValue = atof(filterValue); status = hfs->startScan(filterAttr->attrOffset, filterAttr->attrLen, (Datatype) filterAttr->attrType, (char *)&floatValue, (Operator) op); break; } if(status != OK) { delete hfs; return status; } } while ((status = hfs->scanNext(rid)) == OK) { if (status == OK) { status = hfs->getRecord(rec); if (status != OK) break; attrInfo attrList[projCnt]; int value = 0; char buffer[33]; float fValue; for(int i = 0; i < projCnt; i++) { AttrDesc attrDesc = projNames_Descs[i]; strcpy(attrList[i].relName, attrDesc.relName); strcpy(attrList[i].attrName, attrDesc.attrName); attrList[i].attrType = attrDesc.attrType; attrList[i].attrLen = attrDesc.attrLen; attrList[i].attrValue = (void *) malloc(attrDesc.attrLen); switch(attrList[i].attrType) { case STRING: memcpy((char *)attrList[i].attrValue, (char *)(rec.data + attrDesc.attrOffset), attrDesc.attrLen); break; case INTEGER: memcpy(&value, (int *)(rec.data + attrDesc.attrOffset), attrDesc.attrLen); sprintf((char *)attrList[i].attrValue, "%d", value); break; case FLOAT: memcpy(&fValue, (float *)(rec.data + attrDesc.attrOffset), attrDesc.attrLen); sprintf((char *)attrList[i].attrValue, "%f", fValue); break; } } status = QU_Insert(result, projCnt, attrList); if(status != OK) { delete hfs; return status; } } } return OK; }