RC SM_Manager::DropTable(const char *relName){ string rel_name(relName); //drop in system catalog RM_FileScan system_scanner(system_fh, STRING, RELNAME_LENGTH, 0, EQ_OP, (void*)relName, strlen(relName)); RC ret; RM_Record record; ret=system_scanner.GetNextRec(record); if (ret==NOT_FOUND){ return NOT_FOUND; } RID rid; record.GetRid(rid); system_fh.DeleteRec(rid); //------------------------ //drop in attribute catalog RM_FileScan attribute_scanner(attribute_fh, STRING, RELNAME_LENGTH, 0, EQ_OP, (void*)relName, strlen(relName)); while( (ret=attribute_scanner.GetNextRec(record)) != NOT_FOUND ){ record.GetRid(rid); attribute_fh.DeleteRec(rid); } system((string("mv -f ")+db_dir+string(relName)+" "+db_dir+"dust/"+string(relName)).c_str()); RM_FileScan check_scanner(check_fh, STRING, RELNAME_LENGTH, 0, EQ_OP, (void*)relName, strlen(relName)); while( (ret=attribute_scanner.GetNextRec(record)) != NOT_FOUND ){ Byte *mem; record.GetRid(rid); record.GetData(mem); attribute_fh.DeleteRec(rid); string CheckData=string("__checkdata__")+rel_name+(char*)(mem+RELNAME_LENGTH); system((string("mv -f ")+db_dir+CheckData+" "+db_dir+"dust/"+CheckData).c_str()); } attribute_fh.ForcePages(); system_fh.ForcePages(); check_fh.ForcePages(); //----------------------- return OK; }
int RM_FileHandle::UpdateRec(RID &rid, RM_Record &rec) { int index; Bytes head = (Bytes)bpm->getPage(fileid, rid.GetPageid(), index); Bits* slots = new Bits(head, pernum); if (!slots->bit_get(rid.GetSlotid())) { //cout << "[RM_FileHandle-Update]Warning: RID doesn't exist,Maybe need Insert" << endl; return 1; } int offset = PAGE_HEAD_BYTE; offset = offset + recordsize * rid.GetSlotid(); Bytes rlocation = (Bytes)head; rlocation = rlocation + offset; memcpy(rlocation, rec.GetRdata(), rec.GetSize()); slots->bit_setone(rid.GetSlotid()); bpm->markDirty(index); return 0; }
bool SM_Manager::checkNotNull(const char*relName,const char *AttrName){ RM_FileScan attribute_scanner(attribute_fh, STRING, RELNAME_LENGTH, 0, EQ_OP, (void*)relName, strlen(relName)); RC ret; RM_Record record; Byte *mem; int cnt=0; while( (ret=attribute_scanner.GetNextRec(record)) != NOT_FOUND ){ // record.GetRid(rid); // attribute_fh.DeleteRec(rid); record.GetData(mem); if (strcmp((char*)mem+RELNAME_LENGTH,AttrName)==0){ // cout<<"get "<< AttrName<<" "<<*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+16)<<endl; return *(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+16); } } return false; }
bool SM_Manager::hasKey(const char *relName,int &offset,int &length,AttrType &attrtype){ RM_FileScan attribute_scanner(attribute_fh, STRING, RELNAME_LENGTH, 0, EQ_OP, (void*)relName, strlen(relName)); RC ret; RM_Record record; Byte *mem; while( (ret=attribute_scanner.GetNextRec(record)) != NOT_FOUND ){ // record.GetRid(rid); // attribute_fh.DeleteRec(rid); record.GetData(mem); if ((*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+12)/2)==1){ offset=*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH); length=*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+8); attrtype=(AttrType)*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+4); return true; } } return false; }
RC SM_Manager::ShowTable (){ RM_FileScan system_scanner(system_fh, STRING, RELNAME_LENGTH, 0, EQ_OP, NULL, 0); //cout<<"1"<<endl; RC ret; RM_Record record; Byte *mem; //cout<<"1.1"<<endl; while( (ret=system_scanner.GetNextRec_NoComp(record)) != NOT_FOUND ){ // record.GetRid(rid); // attribute_fh.DeleteRec(rid); // cout<<"2"<<endl; record.GetData(mem); // cout<<"3"<<endl; cout<<GenString((char *)(mem),RELNAME_LENGTH)<<"("<<*(int*)(mem+RELNAME_LENGTH)<<")"<<endl; //cout<<"4"<<endl; } return OK; } // Print table
bool SM_Manager::hasIndex(const char *relName,const char *AttrName,int &offset,int &length,AttrType &attrtype){ RM_FileScan attribute_scanner(attribute_fh, STRING, RELNAME_LENGTH, 0, EQ_OP, (void*)relName, strlen(relName)); RC ret; RM_Record record; Byte *mem; while( (ret=attribute_scanner.GetNextRec(record)) != NOT_FOUND ){ // record.GetRid(rid); // attribute_fh.DeleteRec(rid); record.GetData(mem); if (GenString((char *)(mem+RELNAME_LENGTH),ATTRNAME_LENGTH)==GenString((char *)AttrName,strlen(AttrName))){ offset=*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH); length=*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+8); attrtype=(AttrType)*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+4); //cout<<(*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+12))<<endl; return ((*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+12))%2)!=0; } } return OK; }
int SM_Manager::Getoffset(const char *relName,int *offset,int *length){ RM_FileScan attribute_scanner(attribute_fh, STRING, RELNAME_LENGTH, 0, EQ_OP, (void*)relName, strlen(relName)); RC ret; RM_Record record; Byte *mem; int cnt=0; while( (ret=attribute_scanner.GetNextRec(record)) != NOT_FOUND ){ // record.GetRid(rid); // attribute_fh.DeleteRec(rid); record.GetData(mem); //if (genString((char *)(mem+RELNAME_LENGTH),ATTRNAME_LENGTH)==genString(AttrName,strlen(AttrName))){ offset[cnt]=*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH); length[cnt]=*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+8); cnt++; // attrtype=*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+4); //} } return cnt; }
void SM_Manager::GetAttrName(const char *relName,char attrNames[100][100],bool *ischecked,bool *isnotnull,AttrType* attrType){ RM_FileScan attribute_scanner(attribute_fh, STRING, RELNAME_LENGTH, 0, EQ_OP, (void*)relName, strlen(relName)); RC ret; RM_Record record; Byte *mem; int cnt=0; while( (ret=attribute_scanner.GetNextRec(record)) != NOT_FOUND ){ // record.GetRid(rid); // attribute_fh.DeleteRec(rid); record.GetData(mem); //if (genString((char *)(mem+RELNAME_LENGTH),ATTRNAME_LENGTH)==genString(AttrName,strlen(AttrName))){ memcpy(attrNames[cnt],(mem+RELNAME_LENGTH),ATTRNAME_LENGTH-1); ischecked[cnt]=isChecked(relName,attrNames[cnt]); isnotnull[cnt]=checkNotNull(relName,attrNames[cnt]); attrType[cnt]=(AttrType)*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+4); cnt++; // attrtype=*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+4); //} } }
RC QL_JoinNode::GetNext(RM_Record &rec) { RM_Record leftRec; RM_Record rightRec; while(true) { if (bRightNodeEOF) { if (lSubNode.GetNext(leftRec) == QL_EOF) return QL_EOF; memcpy(buffer, leftRec.GetContent(), leftRec.GetRecordSize()); bRightNodeEOF = false; } if (rSubNode.GetNext(rightRec) == QL_EOF) { bRightNodeEOF = true; rSubNode.Reset(); continue; } memcpy(buffer + lSubNode.GetTupleLength(), rightRec.GetContent(), rSubNode.GetTupleLength()); RID rid(-1, -1); rec = RM_Record(buffer, rid, tupleLength); return 0; } }
void SM_Manager::DropIndex(const char *relName, const char* AttrName) { RM_FileScan attribute_scanner(attribute_fh, STRING, RELNAME_LENGTH, 0, EQ_OP, (void*)relName, strlen(relName)); RC ret; RM_Record record; Byte *mem; RID rid; int mark=0; while( (ret=attribute_scanner.GetNextRec(record)) != NOT_FOUND ){ record.GetRid(rid); // attribute_fh.DeleteRec(rid); record.GetData(mem); if (GenString((char *)(mem+RELNAME_LENGTH),ATTRNAME_LENGTH)==GenString((char *)AttrName,strlen(AttrName))){ mark=*(int*)(mem+RELNAME_LENGTH+ATTRNAME_LENGTH+12); if(mark&1) mark=mark-1; memcpy((mem+RELNAME_LENGTH+ATTRNAME_LENGTH+12), &mark , 4); RM_Record rec=RM_Record(mem, attribute_fh.GetRecordSize(), rid); attribute_fh.UpdateRec(rec); } } attribute_fh.ForcePages(); }
int RM_FileHandle::InsertRec(RID &rid, RM_Record &rec) { //这里的RID是插入后返回一个RID,其余成员函数都是需要一个RID int first_index; BufType first_head = bpm->getPage(fileid, 0, first_index); int empty_rid_offset = EMPTY_RID_OFFSET_BYTE; //获取下一可插入项的偏移 int next_page_offset = NEXT_EMPTY_PAGE_BYTE; //获取下一个含空项页页码的偏移 int slots_offset = SLOT_OFFSET_BYTE; //获取slot偏移位置 if (*(int*)(first_head + EMPTY_PAGE_OFFSET_4BYTE) != -1) { //存在下一个空记录 int insert_page_index; Bytes insert_page_head = (Bytes)bpm->getPage(fileid, first_head[EMPTY_PAGE_OFFSET_4BYTE], insert_page_index); bpm->markDirty(insert_page_index); //肯定要修改,所以提前标记为脏页 RID* current_empty_rid = (RID*)(insert_page_head + empty_rid_offset); //下一可插入项 int next_page = *(int*)(insert_page_head + next_page_offset); //下一个含空项页页码 Bits* slots = new Bits(insert_page_head + slots_offset, pernum); //slots int offset = PAGE_HEAD_BYTE; offset = offset + recordsize * current_empty_rid->GetSlotid(); Bytes rlocation = insert_page_head + offset; //获取相应偏移后的地址 memcpy(rlocation, rec.GetRdata(), rec.GetSize()); //插入该记录 slots->bit_setone(current_empty_rid->GetSlotid()); //slot相应位子置1 rid = *current_empty_rid; //rid返回 bool isfull = true; //标记用,true表示当前页满 for (int current_slot = current_empty_rid->GetSlotid() + 1; current_slot < pernum; current_slot++) { if (!slots->bit_get(current_slot)) { //寻找下一个current_empty_rid,当slots[i]为0时说明该位为空 isfull = false; current_empty_rid->SetSlotid(current_slot); //修改下一个空项的位置 break; } } if (isfull) { //如果页满了 first_head[EMPTY_PAGE_OFFSET_4BYTE] = next_page; //当前数据页的下一页给第一页的含空项页 bpm->markDirty(first_index); //标记脏页 current_empty_rid->SetSlotid(-1); //slotid为-1表示没有下一项 *(int*)(insert_page_head + next_page_offset) = -1; //下一个含空项页页码表示当前页为满页 } } else { //均为满页,新建一页 pagesum++; //总页数新增一页 first_head[PSIZE_OFFSET_4BYTE] = pagesum; //修改总页数 bpm->markDirty(first_index); //标记为脏页 int new_index; //新建一个页,并将slot清零 Bytes new_head = (Bytes)bpm->getPage(fileid, pagesum - 1, new_index); Bits* new_slots = new Bits(new_head + slots_offset, pernum); new_slots->all_zero(); int new_offset = PAGE_HEAD_BYTE; //slot[0]即为第一条记录,存储insert的记录 Bytes rlocation = new_head + new_offset; memcpy(rlocation, rec.GetRdata(), rec.GetSize()); new_slots->bit_setone(0); bpm->markDirty(new_index); //标记为脏页 RID new_rid; new_rid.SetFileid(-1); new_rid.SetPageid(pagesum - 1); new_rid.SetSlotid(1); *(RID*)(new_head + empty_rid_offset) = new_rid; //下一可插入项更新为第1项 rid = new_rid; rid.SetSlotid(0); first_head[EMPTY_PAGE_OFFSET_4BYTE] = pagesum - 1; //第一页的含空项页设为当下的新增页 *(int*)(new_head + next_page_offset) = -1; //由于之前都是满页,这页显然没有后继页面,设为-1 } return 0; }
int RM_FileScan::NextRec(RM_Record &rec, RID &rid) { if (isclose) { //cout << "[RM_FileScan]GetNextRec error: This filescan has been closed!" << endl; return 2; } //NULL1:当comparevalue为NULL且op为大小于中的一个时为用假,返回为空 if(op <= GE && op >= LT && comparevalue == NULL) return 1; bool get_flag = false; int index; Bytes head = (Bytes)filehandle->bpm->getPage(currentRid->GetFileid(), currentRid->GetPageid(), index); Bits* slots = new Bits(head, filehandle->GetPnum()); Bytes record_head; int current_slotid = currentRid->GetSlotid(); int current_pageid = currentRid->GetPageid(); int offset = PAGE_HEAD_BYTE; while (!get_flag) { // cout << "fuck1" << endl; while ( current_slotid < filehandle->GetPnum() && slots->bit_get(current_slotid) == false) { current_slotid++; } // cout << "fuck2" << endl; if (current_slotid == filehandle->GetPnum()) { //该页记录已全部遍历 current_pageid++; current_slotid = 0; if (current_pageid == filehandle->GetPsum()) { //说明该文件下所有页的所有记录都已遍历过.此时返回0表示已遍历完 currentRid->SetPageid(current_pageid); currentRid->SetSlotid(current_slotid); return 1; } head = (Bytes)filehandle->bpm->getPage(currentRid->GetFileid(), current_pageid, index); slots->setData(head); offset = PAGE_HEAD_BYTE; } else { //得到一个记录 // cout << "fuck3" << endl; offset = PAGE_HEAD_BYTE; offset = offset + filehandle->GetRsize() * current_slotid; record_head = head + offset; int nullbits_offset = RECORD_NULLBITS_OFFSET_BYTE; Bits* nullbits = new Bits(record_head + nullbits_offset, attrcol+1); //获取相应记录的null位图(一定长度) //NULL2.1:左边NULL且需要判等(不等),则直接通过null位图来判别 //NULL2.2:左边NULL且op为大小于,直接返回true // cout << "fuck3.1" << endl; if(nullbits->bit_get(attrcol) == 0) {//左边为NULL if(op == NO) { get_flag = true; } if(op <= GE && op >= LT) { //为理解方便写出来,实际没什么用 get_flag = false; } if(op == EQ) { get_flag = (comparevalue == NULL); } if(op == NE) { get_flag = !(comparevalue == NULL); } } else /*if (comparevalue != 0)*/{//其他情况,进行相应比较 // cout << "fuck3.2" << endl; char* value_head = record_head + attroffset; // enum AttrType{INTEGER,FLOAT,STRING}; // enum CompOp{EQ,LT,GT,LE,GE,NE,NO}; // cout << "11" << endl; const char* cmp1 = value_head; const char* cmp2 = (char*)comparevalue; const CompOp cmpop = op; const AttrType cmptype = type; // cout << "22" << endl; if (comparevalue != 0 || op == NO){ // cout << "33" << endl; get_flag = compareData(cmp1, cmpop, cmp2, cmptype); } else get_flag = false; } // cout << "fuck4" << endl; if (get_flag) { rec.SetSize(filehandle->GetRsize()); // cout << "get_data: " << &get_data << " " << "head: " << &record_head << endl; rec.SetData(record_head); } else { current_slotid++; } // cout << "fuck5" << endl; } } //设置RID rid.SetFileid(-1); rid.SetPageid(current_pageid); rid.SetSlotid(current_slotid); //设置下一条记录的位置 currentRid->SetPageid(current_pageid); currentRid->SetSlotid(current_slotid + 1); return 0; }
RC RM_FileScan::GetNextRec(RM_Record &rec) { if (!bInScan) return RM_ERR_NOTINSCAN; RC rc; RID rid; RM_Record tmpRec; while (1) { //std::cout <<"start next : "<< nowPage <<" "<<nowSlot<<"\n"; if (bNextPage) { //std::cout << "before next page:" << nowPage<<"\n"; if (PF_ERR_EOF == fileHandle.pfh.GetNextPage(nowPage, nowPH)) { bInScan = false; return RM_ERR_EOF; } if (rc = nowPH.GetPageNum(nowPage)) return rc; //std::cout << "after next page:" << nowPage<<"\n"; bNextPage = false; nowSlot = -1; continue; } char *pData; if (rc = nowPH.GetData(pData)) return rc; BitMap bitmap; if (rc = fileHandle.GetBitMapFromData(pData, bitmap)) return rc; //bitmap.print(); int nextBit; if (RM_ENDOFPAGE == bitmap.GetNextBit(nowSlot, nextBit)) { if (rc = fileHandle.pfh.UnpinPage(nowPage)) return rc; bNextPage = true; continue; } //std::cout << "nextbit: " << nextBit <<"\n"; nowSlot = nextBit; RID rid; rid.SetPageNum(nowPage); rid.SetSlotNum(nowSlot); // std::cout << "find slot: pageNum:"<<nowPage<<" slotNum:"<<nowSlot<<"\n"; //std::cout << "recordSize:" << fileHandle.header.recordSize<<"\n"; //std::cout << "firstFree :" << fileHandle.header.firstFree <<"\n"; //std::cout << "bitmapOffset :" << fileHandle.header.bitmapOffset <<"\n"; //std::cout << "bitmapSize : " << fileHandle.header.bitmapSize <<"\n"; //std::cout << "numRecordsPerPage : " << fileHandle.header.numRecordsPerPage <<"\n"; //std::cout << "numPages : " << fileHandle.header.numPages <<"\n"; //std::cout << rid.pageNum <<" "<<rid.slotNum<<"\n"; if (rc = fileHandle.GetRecordFromData(pData, rid, tmpRec)) return rc; //for (int i = 0; i < fileHandle.header.recordSize; i++) // std::cout << (int)tmpRec.pData[i] <<" "; //std::cout <<"\n"; //std::cout << "recdata: " << (int)tmpRec.pData[3]<<"\n"; //std::cout << "offset:"<<attrOffset<<" "<<" len:"<<attrLength<<" type:"<<attrType<<"\n"; //std::cout << "compop:"<<this->compOp<<"\n"; char *tmpRecData; if (rc = tmpRec.GetData(tmpRecData)) return rc; if (this->compOp != NO_OP) { bool flag; if (this->compOp != IS_OP && this->compOp != IS_NOT_OP && tmpRec.IsNull(attrNumber)) flag = false; else flag = (* cmp)(tmpRecData + attrOffset, this->value, attrType, attrLength); if (flag) { rec = tmpRec; break; } } else { rec = tmpRec; break; } } return 0; }
void test_QM() { int attrcount = 4; AttrInfo attrlist[4]; char aname1[] = "id"; char aname2[] = "age"; char aname3[] = "gender"; char aname4[] = "nationality"; strcpy(attrlist[0].attrName, aname1); strcpy(attrlist[1].attrName, aname2); strcpy(attrlist[2].attrName, aname3); strcpy(attrlist[3].attrName, aname4); attrlist[0].attrLenth = 8; attrlist[1].attrLenth = 8; attrlist[2].attrLenth = 8; attrlist[3].attrLenth = 15; attrlist[0].attrType = INTEGER; attrlist[1].attrType = INTEGER; attrlist[2].attrType = INTEGER; attrlist[3].attrType = STRING; attrlist[0].notNull = true; attrlist[1].notNull = false; attrlist[2].notNull = true; attrlist[3].notNull = true; FileManager* fm = new FileManager(); BufPageManager* bpm = new BufPageManager(fm); RM_Manager* rmm = new RM_Manager(bpm); IX_Manager* ixm = new IX_Manager(); SM_Manager* smm = new SM_Manager(rmm, ixm, currentdb, dbIsOpen); QL_Manager* qlm = new QL_Manager(smm, ixm, rmm, currentdb, dbIsOpen); string db1 = "db1"; string db2 = "db2"; string db3 = "db3"; string table1 = "table1"; string table2 = "table2"; string table3 = "table3"; smm->createDb(db1); smm->createDb(db2); smm->useDb(db1); smm->createTable(table1, 4, attrlist, -1); smm->createTable(table2, 4, attrlist, -1); cout << endl << "test insert----------------------" << endl; int nValues = 4; Value *values = new Value[nValues]; for (long long i = 1; i < 10; ++i) { cout << "id = " << i << endl; long long id = i; long long age1 = 10 - i; long long gender1 = i + 15; char nationality1[] = "China"; values[0].type = INTEGER; values[0].data = (void *) (&id); values[1].type = INTEGER; values[1].data = (void *) (&age1); values[2].type = INTEGER; values[2].data = (void *) (&gender1); values[3].type = STRING; values[3].data = (void *) nationality1; if(qlm->Insert(table1, nValues, values) != 0){ cout << "insert table1 failed" << endl; } } int nValues2 = 4; Value *values2 = new Value[nValues2]; for (long long i = 1; i < 10; ++i) { cout << "id = " << i << endl; long long id = i+1; long long age1 = 15 - i; long long gender1 = i + 60; char nationality1[] = "China"; values2[0].type = INTEGER; values2[0].data = (void *) (&id); values2[1].type = INTEGER; values2[1].data = (void *) (&age1); values2[2].type = INTEGER; values2[2].data = (void *) (&gender1); values2[3].type = STRING; values2[3].data = (void *) nationality1; if (qlm->Insert(table2, nValues2, values2) != 0) { cout << "insert table1 failed" << endl; } } cout << endl << "test delete----------------------" << endl; WhereNode *whereExpr2 = new WhereNode; whereExpr2->type = CONDITION; Condition condition2; condition2.lhsAttr.relName = table1; condition2.lhsAttr.attrName = "id"; condition2.op = LE; condition2.bRhsIsAttr = 0; double id_delete2 = 3; condition2.rhsValue.type = FLOAT; condition2.rhsValue.data = (void *)(&id_delete2); whereExpr2->pData = (void *)(&condition2); whereExpr2->lc = NULL; whereExpr2->rc = NULL; WhereNode *whereExpr3 = new WhereNode; whereExpr3->type = CONDITION; Condition condition3; condition3.lhsAttr.relName = table1; condition3.lhsAttr.attrName = "age"; condition3.op = LE; condition3.bRhsIsAttr = 0; double id_delete3 = 3; condition3.rhsValue.type = FLOAT; condition3.rhsValue.data = (void *)(&id_delete3); whereExpr3->pData = (void *)(&condition3); whereExpr3->lc = NULL; whereExpr3->rc = NULL; WhereNode *whereExpr1 = new WhereNode; whereExpr1->type = LOGIC_OP; LogicOp logic_op = OR; whereExpr1->pData = (void *)(&logic_op); whereExpr1->lc = whereExpr2; whereExpr1->rc = whereExpr3; WhereNode *whereExpr5 = new WhereNode; whereExpr5->type = CONDITION; Condition condition5; condition5.lhsAttr.relName = table1; condition5.lhsAttr.attrName = "id"; condition5.op = EQ; condition5.bRhsIsAttr = 1; condition5.rhsAttr.relName = table2; condition5.rhsAttr.attrName = "id"; whereExpr5->pData = (void *)(&condition5); whereExpr5->lc = NULL; whereExpr5->rc = NULL; WhereNode *whereExpr4 = new WhereNode; whereExpr4->type = LOGIC_OP; LogicOp logic_op4 = AND; whereExpr4->pData = (void *) (&logic_op4); whereExpr4->lc = whereExpr1; whereExpr4->rc = whereExpr5; qlm->Delete(table1, whereExpr1); cout << endl << "test select 1 table----------------------" << endl; /*int nSelAttrs = 2; RelAttr *selAttrs = new RelAttr[nSelAttrs]; selAttrs[0].relName = table1; selAttrs[0].attrName = "id"; selAttrs[1].relName = table1; selAttrs[1].attrName = "age";*/ int nSelAttrs = -1; RelAttr *selAttrs = NULL;/**/ int nRelations = 1; string *relations = new string[nRelations]; relations[0] = table1; //qlm->Select(nSelAttrs, selAttrs, nRelations, relations, whereExpr1); //qlm->Select(nSelAttrs, selAttrs, nRelations, relations, NULL); cout << endl << "test select 2 table----------------------" << endl; int nSelAttrs2 = 3; RelAttr *selAttrs2 = new RelAttr[nSelAttrs2]; selAttrs2[0].relName = table1; selAttrs2[0].attrName = "id"; selAttrs2[1].relName = table1; selAttrs2[1].attrName = "age"; selAttrs2[2].relName = table2; selAttrs2[2].attrName = "gender"; /*int nSelAttrs2 = -1; RelAttr *selAttrs2 = NULL;*/ int nRelations2 = 2; string *relations2 = new string[nRelations2]; relations2[0] = table1; relations2[1] = table2; //qlm->Select(nSelAttrs2, selAttrs2, nRelations2, relations2, whereExpr5); //qlm->Select(nSelAttrs2, selAttrs2, nRelations2, relations2, NULL); cout << endl << "test update----------------------" << endl; ExcNode *excLc = new ExcNode; excLc->type = VALUE; Value value_lc; double upd = 40; value_lc.type = FLOAT; value_lc.data = (void *)(&upd); excLc->pData = (void *)(&value_lc); excLc->lc = excLc->rc = NULL; ExcNode * excRc = new ExcNode; excRc->type = RELATTR; RelAttr attrRc; attrRc.relName = table1; attrRc.attrName = "age"; excRc->pData = (void *)(&attrRc); excRc->lc = excRc->rc = NULL; ExcNode *excRoot = new ExcNode; excRoot->type = ARITH_OP; ArithOp op = ADD; excRoot->pData = (void *)(&op); excRoot->lc = excLc; excRoot->rc = excRc; RelAttr updAttr; updAttr.relName = table1; updAttr.attrName = "age"; //qlm->Update(table1, updAttr, excRoot, whereExpr1); //全表扫描 cout << endl << "全表扫描 table1----------------------" << endl; string new_relName = currentdb + "/" + table1; RM_FileHandle rm_handler; rmm->OpenFile(new_relName.c_str(), rm_handler); RM_FileScan rm_scan; rm_scan.OpenScan(rm_handler, NONETYPE, 0, 0, 0, NO, NULL); RM_Record record; RID rid; while(rm_scan.GetNextRec(record, rid) == 0){ char *rbytes = record.GetRdata(); cout << *(long long*)(rbytes + 8) << " " << *(long long*)(rbytes + 16) << " " << *(long long*)(rbytes + 24) << " " << rbytes + 32 << endl; delete []rbytes; } rm_scan.CloseScan(); rmm->CloseFile(rm_handler); cout << endl << "全表扫描 table2----------------------" << endl; new_relName = currentdb + "/" + table2; rmm->OpenFile(new_relName.c_str(), rm_handler); rm_scan.OpenScan(rm_handler, NONETYPE, 0, 0, 0, NO, NULL); while (rm_scan.GetNextRec(record, rid) == 0) { char *rbytes = record.GetRdata(); cout << *(long long*) (rbytes + 8) << " " << *(long long*) (rbytes + 16) << " " << *(long long*) (rbytes + 24) << " " << rbytes + 32 << endl; delete []rbytes; } rm_scan.CloseScan(); rmm->CloseFile(rm_handler); delete []values; delete fm; delete bpm; delete rmm; delete ixm; delete smm; delete qlm; }
RC QL_Manager::GenColumn(vector<int> *pvGroup, vector<RM_Record> *pvRecord, vector<Column> &columns) { RC rc; bool flagAllAttr = false; if (rmp.nSelAttrs == 1 && (strcmp(rmp.selAttrs[0].attrName, "*") == 0)) { flagAllAttr = true; } if (flagAllAttr) { for (int i = 0; i < rmp.nSelRels; i++) { vector<SM_ActiveAttr> *vAttr; if (rc = db.AllAttributes(rmp.selRels[i], vAttr)) return rc; for (int j = 0; j < vAttr->size(); j++) { Column column; column.attrLength = (*vAttr)[j].record.attrLength; column.attrType = (*vAttr)[j].record.attrType; column.relName = string((*vAttr)[j].record.tableName); column.attrName = string((*vAttr)[j].record.attrName); int number = (*vAttr)[j].record.number; int offset = (*vAttr)[j].record.attrOffset; int length = (*vAttr)[j].record.attrLength; for (int k = 0; k < pvGroup[i].size(); k++) { int pos = pvGroup[i][k]; RM_Record rec = pvRecord[i][pos]; if (rec.IsNull(number)) { char *c = new char[4]; strcpy(c, "NULL"); column.vData.push_back(c); } else if (column.attrType == INT) { int *p = new int; *p = *(int *)(rec.pData + offset); column.vData.push_back(p); } else if (column.attrType == STRING) { char *c = new char[length]; memcpy(c, rec.pData + offset, length); column.vData.push_back(c); } } columns.push_back(column); } } } else { for (int i = 0; i < rmp.nSelAttrs; i++) { char *relName = rmp.selAttrs[i].relName; char *attrName = rmp.selAttrs[i].attrName; if (relName == NULL) relName = rmp.selRels[0]; SM_Attribute *smAttr; if (rc = db.FindAttribute(relName, attrName, smAttr)) return rc; Column column; column.attrLength = smAttr->attrLength; column.attrType = smAttr->attrType; column.relName = string(relName); column.attrName = string(attrName); int offset = smAttr->attrOffset; int length = smAttr->attrLength; for (int j = 0; j < rmp.nSelRels; j++) if (strcmp(relName, rmp.selRels[j]) == 0) { for (int k = 0; k < pvGroup[j].size(); k++) { int pos = pvGroup[j][k]; RM_Record rec = pvRecord[j][pos]; if (column.attrType == INT) { int *p = new int; *p = *(int *)(rec.pData + offset); column.vData.push_back(p); } else if (column.attrType == STRING) { char *c = new char[length]; memcpy(c, rec.pData + offset, length); column.vData.push_back(c); } } break; } columns.push_back(column); } } return 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; }