📄 record.cpp
字号:
#include"Buffer.h"
#include"Glob_Var.h"
#include"Record.h"
#include <string.h>
extern _M_Buffer Buffer;
/////////////////////////////////////////////////////////////////////////////////////
//构建 Record
Record::Record()
{
char address[256]; //存放文件地址
strcpy(address,CurLocation);
strcat(address,CurRelationName);
strcat(address,".dbf"); //扩展名
_M_File TargetF = Buffer[address];
this->m_DbfFile=&TargetF;
this->m_DelList = (_F_DELLIST*)(TargetF.GetDelListCond().MemAddr());
}
////////////////////////////////////////////////////////////////////////////////////
//函数
//插入一个TUPLE语句
_F_FileAddr Record::Insert(Rec_Info& RecInfo)
{
//将Buffer指针指向当前文件
char address[256];
strcpy(address,CurLocation);
strcat(address,CurRelationName);
strcat(address,".dbf");
_M_File targettb = Buffer[address];
Cell_Info* temp = RecInfo.head; //存改指向单个Column 的信息
_F_FileAddr InsertPlace,TargetPlace; //存放临时头信息
if(this->m_DelList->DelFirst.uiOffset==0) //Have no DelList
{
TargetPlace=InsertPlace=this->m_DelList->NewInsert; //取头地址
this->m_DelList->NewInsert = MemWriteTest(RecInfo.RecordLength + sizeof(_F_FileAddr),&InsertPlace);
}
else if(this->m_DelList->DelFirst==this->m_DelList->DelLast)//Just have one tuple have being delete
{
TargetPlace=InsertPlace=this->m_DelList->DelFirst; //取头地址
this->m_DelList->DelFirst.Initialize();
this->m_DelList->DelLast.Initialize();
}
else
{
TargetPlace=InsertPlace=this->m_DelList->DelFirst; //取头地址
this->m_DelList->DelFirst=*(_F_FileAddr*)(this->m_DelList->DelFirst.MemAddr());
}
//InsertPlace.Status='u';TargetPlace=InsertPlace;如果有遍历整个文件功能
InsertPlace = MemWrite((void*)&InsertPlace,sizeof(_F_FileAddr),&TargetPlace);//Write the head of one tuple
//Write the cell information插入数据
while(temp)
{
switch(temp->ColType)
{
case I: //int 型数据 写信息
InsertPlace = MemWrite((void*)&temp->value.IntValue,temp->ColLength,&InsertPlace);
break;
case F: //float 型数据 写信息
InsertPlace = MemWrite((void*)&temp->value.FloatValue,temp->ColLength,&InsertPlace);
break;
case C: //char 型数据 写信息
InsertPlace = MemWrite((void*)temp->value.pCharValue,temp->ColLength,&InsertPlace);
break;
}
temp = temp->next;//到下一个Column
}
return TargetPlace;//返回地址合INDEXT
}
//删除一个tuple语句
void Record::Delete(_F_FileAddr& DFAddr)
{
//将Buffer指针指向当前文件
char address[256];
strcpy(address,CurLocation);
strcat(address,CurRelationName);
strcat(address,".dbf");
_M_File targettb = Buffer[address];
_F_FileAddr * FPTemp;
//DFAddr.Status='l';如果有遍历整个文件功能
FPTemp = (_F_FileAddr*)DFAddr.MemAddr();//取得文件中的单语句头信息
if(*FPTemp!= DFAddr )//信息与所要Delete的不一样
{
cout<<"Already deleted or Required record does not exsit.\n";
return;
}
_F_FileAddr ZPtr;
ZPtr.Initialize();
//ZPtr.Status='l';如果有遍历整个文件功能
MemWrite(&ZPtr,sizeof(_F_FileAddr),FPTemp);//将被删除处的头信息写空
if(this->m_DelList->DelFirst.uiOffset==0)//如果Dellist为空
{
this->m_DelList->DelFirst=DFAddr;
this->m_DelList->DelLast=DFAddr;
}
else
{//将当前删除语句的头信息写入前一删除语句的头地址以使删除空间链在一起
MemWrite((void*)&DFAddr,sizeof(_F_FileAddr),&this->m_DelList->DelLast);
this->m_DelList->DelLast = DFAddr;
}
}
//查找一个TUPLE语句
Rec_Info* Record::Select(_F_FileAddr& FAddr,Select_Rec_Info& SelRecInfo) const
{
//将Buffer指针指向当前文件
char address[256];
strcpy(address,CurLocation);
strcat(address,CurRelationName);
strcat(address,".dbf");
_M_File targettb = Buffer[address];
Rec_Info* RPRecInfo = new class Rec_Info;//存放Select出来的信息
TCell_Info* CPTemp =NULL;
TCell_Info* CPTemp1= NULL;
RPRecInfo->head=NULL;
//向Rec_Info 写信息
RPRecInfo->ColNum=SelRecInfo.ColumnNum;//所选Column(列数)number
RPRecInfo->RecordLength=SelRecInfo.RecordLength;//所选记录长度
Select_Cell* SPTemp=SelRecInfo.head;
_F_FileAddr temp=*(_F_FileAddr*)FAddr.MemAddr();//取该语句存放地址
if(temp!=FAddr)//与要选择的信息不一致,返回
return 0;
temp.ShiftOffset(sizeof(_F_FileAddr));
while(SPTemp)
{
CPTemp = new Cell_Info;
if(SPTemp == SelRecInfo.head)//第一个Column要链到整条信息的头信息
RPRecInfo->head=CPTemp;
else
{
CPTemp1->next = CPTemp;
}
//对Cell_Info符值
CPTemp1=CPTemp;
CPTemp->ColLength = SPTemp->ColLength;
CPTemp->next = NULL;
CPTemp->ColType = SPTemp->ColType;
CPTemp->PriorLength = SPTemp->PriorLength;
temp.ShiftOffset(SPTemp->PriorLength);//移动OFFSET指针到要读的数据位置
//不同类数据的读取
switch(SPTemp->ColType)
{
case I: CPTemp->value.IntValue = * (int*) temp.MemAddr();
break;
case C: CPTemp->value.pCharValue = new char(SPTemp->ColLength+1);
strcpy(CPTemp->value.pCharValue,(char*)temp.MemAddr());
break;
case F: CPTemp->value.FloatValue = * (float*) temp.MemAddr();
break;
}
temp.ShiftOffset( -SPTemp->PriorLength);//将OFFSET指返回初始值,以便下次便用
SPTemp=SPTemp->next;
}
return RPRecInfo;
}
//更新数据
void Record::Update(_F_FileAddr& UpdateFAddr,Rec_Info& UpdateInfo)
{
//将Buffer指针指向当前文件
char address[256];
strcpy(address,CurLocation);
strcat(address,CurRelationName);
strcat(address,".dbf");
_M_File targettb = Buffer[address];
Cell_Info* temp = UpdateInfo.head;
_F_FileAddr UFATemp = UpdateFAddr;
UFATemp.ShiftOffset(sizeof(_F_FileAddr));
while(temp) //Write the cell information
{
UFATemp.ShiftOffset(temp->PriorLength);
switch(temp->ColType)
{
case I:
MemWrite((void*)&temp->value.IntValue,temp->ColLength,&UFATemp);
break;
case F:
MemWrite((void*)&temp->value.FloatValue,temp->ColLength,&UFATemp);
break;
case C:
MemWrite((void*)temp->value.pCharValue,temp->ColLength,&UFATemp);
break;
}
UFATemp.ShiftOffset(-temp->PriorLength);
temp = temp->next;
}
}
//打印头信息
void Record::PrintHead(Select_Rec_Info& SelRecInfo) const
{
Select_Cell* SPTemp = SelRecInfo.head;
int k = 0;
cout.setf(ios::left,ios::adjustfield);//调整打印宽度
for(k=0;k<SelRecInfo.RecordLength + SelRecInfo.ColumnNum*4;k++)
cout<<"*";
cout<<"*\n* ";
cout.width(SPTemp->ColLength +2);
cout<<SPTemp->ColumnName;
SPTemp = SPTemp->next;
while(SPTemp)
{
cout<<"| ";
cout.width(SPTemp->ColLength +2);//调整打印宽度
cout<<SPTemp->ColumnName;//打印属性名
SPTemp = SPTemp->next;
}
cout<<"*\n";
}
//打印所查到的记录(RECORD)
void Record::Print(_F_FileAddr& pritarget,Select_Rec_Info& prilist) const
{
Rec_Info* temp = this->Select(pritarget,prilist);//调用Select
if(!temp) throw 1030;
Cell_Info* node = temp->head;
cout.setf(ios::left,ios::adjustfield);
cout<<"*";
for(int k=0;k<prilist.RecordLength + prilist.ColumnNum*4 -1;k++)
cout<<"-";
cout<<"*\n* ";
while( node )//打印值
{
switch( node->ColType )
{
case I:
if(node!=temp->head)
cout<<"| ";
cout.width(node->ColLength+2);
cout<<node->value.IntValue;
break;
case C:
if(node!=temp->head)
cout<<"| ";
cout.width(node->ColLength+2);
cout<<node->value.pCharValue;
break;
case F:
if(node!=temp->head)
cout<<"| ";
cout.width(node->ColLength+2);
cout<<node->value.FloatValue;
break;
}
node = node->next;
}
cout<<"*\n";
return;
}
//打印表末尾
void Record::PrintEnd(Select_Rec_Info& SelRecInfo) const
{
cout.setf(ios::left,ios::adjustfield);
for(int k=0;k<SelRecInfo.RecordLength + SelRecInfo.ColumnNum*4;k++)
cout<<"*";
cout<<"*\n";
}
/* 表的形式
**********************************************************************
* | | | | *
*--------------------------------------------------------------------*
* | | | | *
**********************************************************************
//下面是遍历整个文件的代码
int Record::Print(Select_Rec_Info& prilist,Select_Cond_Info &SelCondInfo)
{
//将Buffer指针指向当前文件
char address[256];
strcpy(address,CurLocation);
strcat(address,CurRelationName);
strcat(address,".dbf");
_M_File targettb = Buffer[address];
_F_FileAddr *pFile;
_F_FileAddr FileAddr;
int TotalLength=sizeof(_F_FileAddr)+SelCondInfo.RecordLength;//每条记录的总长度
//所有页进行查找
for(unsigned long i=0;i<targettb.GetPageTotal();i++)
{
//设置每页第一条语句的页数人ID和偏移地址以取得文件指针
if(i==0)
{
//第一页包含了一个文件头信息和一个页头信息
FileAddr.ShiftOffset(sizeof(_TB_FILECOND)+sizeof(_TB_PAGEHEAD));
FileAddr.ulFilePageID=0;
pFile =(_F_FileAddr*)FileAddr.MemAddr();
}
else
{//其它页只有一个页头信息
FileAddr.ShiftOffset(sizeof(_TB_PAGEHEAD));
FileAddr.ulFilePageID=i;
pFile =(_F_FileAddr*) FileAddr.MemAddr();
}
//页内搜索,
while((pFile->uiOffset+TotalLength)<FILE_PAGESIZE)//记录是否溢出,溢出则跳出循环
{
int IfCatch=0;//标记该语句是否为所要找的语句
FileAddr = *pFile;
if(pFile==&this->m_DelList->NewInsert)//到文件尾结整搜索
return 1;
pFile=(_F_FileAddr *)((char*)pFile+TotalLength);//指到下一语句地址
if(FileAddr.Status=='l')//判断该语句是否已删除
continue;
TSelect_Cond_Cell* SCCT=SelCondInfo.head;//搜索条件
Column_Value TempVal;//用于存放临时读取的数据
while(SCCT)//多条件循环
{
FileAddr.ShiftOffset(sizeof(_F_FileAddr)+SCCT->PriorLength);//文件指针移到要读取值的位置
switch(SCCT->ColType)//类型判断
{
case I:TempVal.IntValue=*(int*)FileAddr.MemAddr();
switch(SCCT->OperType)//操作符判断
{
case E:if((TempVal.IntValue-SCCT->ColSelValue.IntValue)==0)
IfCatch=1;
else IfCatch=0;
break;
case B:if((TempVal.IntValue-SCCT->ColSelValue.IntValue)>0)
IfCatch=1;
else IfCatch=0;
break;
case BE:
if((TempVal.IntValue-SCCT->ColSelValue.IntValue)>=0)
IfCatch=1;
else IfCatch=0;
break;
case L:if((TempVal.IntValue-SCCT->ColSelValue.IntValue)<0)
IfCatch=1;
else IfCatch=0;
break;
case LE:if((TempVal.IntValue-SCCT->ColSelValue.IntValue)<=0)
IfCatch=1;
else IfCatch=0;
break;
//default
}break;
case F:TempVal.FloatValue=*(float*)FileAddr.MemAddr();
switch(SCCT->OperType)//操作符判断
{
case E:if((TempVal.FloatValue-SCCT->ColSelValue.FloatValue)==0)
IfCatch=1;
else IfCatch=0;
break;
case B:if((TempVal.FloatValue-SCCT->ColSelValue.FloatValue)>0)
IfCatch=1;
else IfCatch=0;
break;
case BE:
if((TempVal.FloatValue-SCCT->ColSelValue.FloatValue)>=0)
IfCatch=1;
else IfCatch=0;
break;
case L:if((TempVal.FloatValue-SCCT->ColSelValue.FloatValue)<0)
IfCatch=1;
else IfCatch=0;
break;
case LE:if((TempVal.FloatValue-SCCT->ColSelValue.FloatValue)<=0)
IfCatch=1;
else IfCatch=0;
break;
//default
}break;
case C:TempVal.pCharValue=(char*)FileAddr.MemAddr();
switch(SCCT->OperType)//操作符判断
{
case E:
if(strcmp(TempVal.pCharValue,SCCT->ColSelValue.pCharValue)==0)
IfCatch=1;
else IfCatch=0;
break;
case B:
if(strcmp(TempVal.pCharValue,SCCT->ColSelValue.pCharValue)==1)
IfCatch=1;
else IfCatch=0;
break;
case BE:
if((strcmp(TempVal.pCharValue,SCCT->ColSelValue.pCharValue)==0)||(strcmp(TempVal.pCharValue,SCCT->ColSelValue.pCharValue)==1))
IfCatch=1;
else IfCatch=0;
break;
case L:
if(strcmp(TempVal.pCharValue,SCCT->ColSelValue.pCharValue)==-1)
IfCatch=1;
else IfCatch=0;
break;
case LE:
if((strcmp(TempVal.pCharValue,SCCT->ColSelValue.pCharValue)==0)||(strcmp(TempVal.pCharValue,SCCT->ColSelValue.pCharValue)==-1))
IfCatch=1;
else IfCatch=0;
break;
//default
}break;
//default
}
FileAddr.ShiftOffset(-(sizeof(_F_FileAddr)+SCCT->PriorLength));//文件指针回复到初始状态
SCCT=SCCT->next;//下一个条件
}
if(IfCatch)//如果找到符合条件的语句
{
this->Print(FileAddr,prilist);
}
}
}
return 1;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -