📄 record.cpp
字号:
#include "record.h"
#include "btree.h"
RecordHead::RecordHead(bool valid, int recordID, int nextID)
:m_valid(valid),
m_recordID(recordID),
m_nextRecordID(nextID)
{
}
RecordManager::RecordManager(const string & tableName)
{
m_recordAmount=0;
m_firstBlank=-1;
string recdPath("data\\");
recdPath+=tableName;
string cataPath=recdPath;
recdPath+=".recd";
cataPath+=".cata";
m_recdFile.open((recdPath).c_str(), ios::in | ios::out | ios::binary); //打开记录文件
m_cataIn.open((cataPath).c_str(), ios:: in | ios::binary); //打开日志文件
m_cataIn.seekg(16,ios::beg);
m_cataIn.read((char*)&m_attrAmount,sizeof(int)); //日志文件跳过头信息
}
RecordManager::~RecordManager()
{
m_recdFile.close();
m_cataIn.close();
}
int RecordManager::GetRecordAmount() //获取记录条数
{
int amount;
m_recdFile.clear();
m_recdFile.seekg(0,ios::beg);
m_recdFile.read((char *)&amount,sizeof(int));
return amount;
}
int RecordManager::GetFirstBlank() //获取第一个空白记录序号
{
int first;
m_recdFile.seekg(sizeof(int), ios::beg);
m_recdFile.read((char *)&first,sizeof(int));
return first;
}
void RecordManager::WriteFileHead(int amount, int first) //写recd文件头信息
{
m_recdFile.seekp(0, ios::beg);
m_recdFile.write((char *)&amount,sizeof(int));
m_recdFile.write((char *)&first,sizeof(int));
}
void RecordManager::WriteRecord(int id,const vector<string> &v_str,int line)
{
CatalogFile catatmp;
int firsttmp;
m_cataIn.seekg(20,ios::beg);
for(int k=0; k<v_str.size(); k++)
{
m_cataIn.read((char *)&catatmp,sizeof(catatmp));
if(catatmp.primaryFlag==1)
{
if(catatmp.typeFlag==0)
{
Node<char *> charnode;
charnode.Buildtree(string(catatmp.attrName),'a');
if(charnode.Eqsearch(const_cast<char *>(v_str[k].c_str()))[0]!=-1)
throw ErrorPos(ID_ERROR_REPETEVALUE,line);
charnode.Insert_node(const_cast<char *>(v_str[k].c_str()),id);
charnode.Index(string(catatmp.attrName),'a');
}
else if(catatmp.typeFlag==1)
{
Node<int> intnode;
intnode.Buildtree(string(catatmp.attrName),1);
if(intnode.Eqsearch(atoi(v_str[k].c_str()))[0]!=-1)
throw ErrorPos(ID_ERROR_REPETEVALUE,line);
intnode.Insert_node(atoi(v_str[k].c_str()),id);
intnode.Index(string(catatmp.attrName),1);
}
else
{
Node<float> floatnode;
floatnode.Buildtree(string(catatmp.attrName),1.0f);
if(floatnode.Eqsearch(atof(v_str[k].c_str()))[0]!=-1)
throw ErrorPos(ID_ERROR_REPETEVALUE,line);
floatnode.Insert_node(atof(v_str[k].c_str()),id);
floatnode.Index(string(catatmp.attrName),1.0f);
}
break;
}
}
int pos=sizeof(int)*2+(sizeof(RecordHead)+GetSize())*id+sizeof(RecordHead);
m_recdFile.seekp(pos,ios::beg);
for(int j=0; j<v_str.size(); j++)
{
m_cataIn.seekg(20+j*sizeof(catatmp),ios::beg);
m_cataIn.read((char *)&catatmp,sizeof(catatmp));
if(catatmp.typeFlag == 0)
{
string tmp;
tmp=v_str[j].substr(1,v_str[j].size()-2);
if(catatmp.uniqueFlag == 1 && catatmp.primaryFlag != 1)
{
for(int i=0; i!=-1; i=GetRecordHead(i).m_nextRecordID)
{
if(GetRecordAmount()==0){ break; }
while(GetRecordHead(i).m_valid != true && i<GetRecordAmount())
{
i++;
}
if(i==GetRecordAmount())
break;
char *ctmp=new char[catatmp.size+1];
RecordAtrrIO(*ctmp,i,j,'i',4);
if(string(ctmp)==tmp)
throw ErrorPos(ID_ERROR_REPETEVALUE,line);
delete []ctmp;
}
}
m_recdFile.seekp(pos,ios::beg);
pos+=catatmp.size;
m_recdFile.write(tmp.c_str(),catatmp.size);
}
if(catatmp.typeFlag == 1)
{
int itmp;
itmp = atoi(v_str[j].c_str());
if(catatmp.uniqueFlag == 1 && catatmp.primaryFlag != 1)
{
for(int i=0; i!=-1; i=GetRecordHead(i).m_nextRecordID)
{
if(GetRecordAmount()==0){ break; }
while(GetRecordHead(i).m_valid != true && i<GetRecordAmount())
{
i++;
}
if(i==GetRecordAmount())
break;
int iitmp;
RecordAtrrIO(iitmp,i,j,'i',4);
if(iitmp==itmp)
throw ErrorPos(ID_ERROR_REPETEVALUE,line);
}
}
m_recdFile.seekp(pos,ios::beg);
pos+=catatmp.size;
m_recdFile.write((char *)&itmp,catatmp.size);
}
if(catatmp.typeFlag == 2)
{
float ftmp;
ftmp = atof(v_str[j].c_str());
if(catatmp.uniqueFlag == 1 && catatmp.primaryFlag != 1)
{
for(int i=0; i!=-1; i=GetRecordHead(i).m_nextRecordID)
{
if(GetRecordAmount()==0){ break; }
while(GetRecordHead(i).m_valid != true && i<GetRecordAmount())
{
i++;
}
if(i==GetRecordAmount())
break;
float fftmp;
RecordAtrrIO(fftmp,i,j,'i',4);
if(fftmp==ftmp)
throw ErrorPos(ID_ERROR_REPETEVALUE,line);
}
}
m_recdFile.seekp(pos,ios::beg);
pos+=catatmp.size;
m_recdFile.write((char *)&ftmp,catatmp.size);
}
}
RecordHead chead;
firsttmp = chead.m_nextRecordID;
chead.m_recordID=id;
if(id<GetRecordAmount())
{
chead = GetRecordHead(id);
firsttmp = chead.m_nextRecordID;
}
//找到id-1,将它的next赋值给带插入记录的next,将待插入的id赋值给id-1的next
if(id>0)
{
RecordHead phead=GetRecordHead(id-1);
chead.m_nextRecordID = phead.m_nextRecordID;
phead.m_nextRecordID = chead.m_recordID;
WriteRecordHead(id-1,phead);
}
//如果第0条记录为空,则找到最近的一个valid为true的记录赋值给它的next
else
{
if(GetRecordAmount()==0)
{
chead.m_nextRecordID=-1;
}
else
{
for(int i=0; GetRecordHead(i).m_valid == false && i<GetRecordAmount(); i++)
;
if(i==GetRecordAmount())
{
chead.m_nextRecordID=-1;
}
else
{
chead.m_nextRecordID=i;
}
}
}
chead.m_valid=true;
WriteRecordHead(id,chead); //写记录的文件头
if(id<GetRecordAmount())
{
WriteFileHead(GetRecordAmount(),firsttmp); //写文件的文件头
}
else
{
WriteFileHead(GetRecordAmount()+1,firsttmp); //写文件的文件头
}
}
RecordHead RecordManager::GetRecordHead(int currentID) //获取记录头信息
{
RecordHead head;
m_recdFile.seekg(sizeof(int)*2, ios::beg);
m_recdFile.seekg((sizeof(RecordHead)+GetSize())*currentID, ios::cur);
m_recdFile.read((char *) & head, sizeof(head));
return head;
}
void RecordManager::WriteRecordHead(int id, RecordHead head) //写入记录头信息
{
m_recdFile.seekp(sizeof(int)*2, ios::beg);
m_recdFile.seekp((sizeof(RecordHead)+GetSize())*id, ios::cur);
m_recdFile.write((char*) & head, sizeof(head));
}
bool RecordManager::IsEnd(int id) //结束判断
{
return (id==(GetRecordAmount()-1));
}
string RecordManager::GetRecord(int id) //获取一条记录存入string
{
RecordHead head;
string record("");
int itemp=0;
float ftemp=0.0;
int j=0;
for(int i=0; i<m_attrAmount; i++)
{
m_cataIn.seekg(20+i*sizeof(m_cataFile),ios::beg);
m_cataIn.read((char*)&m_cataFile, sizeof(m_cataFile));
switch(m_cataFile.typeFlag)
{
case 0: //char型数据处理
{
char *atemp=new char[m_cataFile.size];
RecordAtrrIO(*atemp,id, i, 'i',m_cataFile.size);
record+=atemp;
delete []atemp;
break;
}
case 1: //int型数据处理
RecordAtrrIO(itemp,id, i, 'i',4);
if(itemp<0)
{
itemp=-itemp;
record.insert(record.end(), '-');
}
for(j=0 ;;j++)
{
record.insert(record.end()-j, itemp%10+'0');
itemp=itemp/10;
if(itemp==0) break;
}
break;
case 2: //float型数据处理
{
RecordAtrrIO(ftemp,id, i, 'i',4);
float temp=ftemp;
if(ftemp<0)
{
ftemp=-ftemp;
record.insert(record.end(), '-');
}
ftemp=int(ftemp*1000);
for(j=0 ;;j++)
{
record.insert(record.end()-j, int(ftemp)%10+'0');
ftemp=int(ftemp/10);
if(int(ftemp)==0) break;
}
if(int(temp)==0)
record+="000";
record.insert(record.size()-3,".");
break;
}
default:break;
}
record+='\t';
}
return record;
}
int RecordManager::GetSize() //获取记录大小
{
int size=0;
CatalogFile catatmp;
m_cataIn.seekg(20,ios::beg);
//m_cataIn.read((char *)&m_attrAmount,sizeof(int));
for(int i=0; i<m_attrAmount; i++)
{
m_cataIn.read((char*)&catatmp, sizeof(catatmp));
size+=catatmp.size;
}
return size;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -