📄 record.cpp
字号:
// Record.cpp: implementation of the Record class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Database.h"
#include "Record.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//非跨块记录首部格式为
//长度(UINT),是否存在(BYTE),记录ID(UINT),时间戳(int)
//长度只包括记录体
//共13字节
Record::Record()
{
body=NULL;
ID=0;
pattern=NULL;
m_length=0;
time=CMemory::GetTime();
}
Record::Record(Relationship *r)
{
WORD i;
ID=0;//暂时
pattern=r;
time=CMemory::GetTime();
m_length=0;//长度只包括记录体
for(i=1;i<=r->attr_num;i++)
{
if(r->at[i].type==CHAR_TYPE)
m_length += r->at[i].length+1;
else if(r->at[i].type==VARCHAR_TYPE)
m_length += r->at[i].length+2;
else
m_length += r->at[i].length;
}
body=new BYTE[m_length];
}
Record::Record(WORD AN,UINT Length):m_length(Length)//,AttrNum(AN)
{
//forward=NULL;
}
BOOL Record::AddValue(CString v,UINT i)
{
BOOL correct=TRUE;
if(i<1||i>pattern->attr_num)
return FALSE;
CString s;
CMemFile cmf;
cmf.Attach(body,m_length);
cmf.Seek(pattern->at[i].offset,CFile::begin);
switch(pattern->at[i].type)
{
case INT_TYPE:
{
int i=0;
correct=CMemory::ATOI(v,i);
if(correct)
cmf.Write(&i,sizeof(int));
break;
}
case FLOAT_TYPE:
{
float i=0;
correct=CMemory::ATOF(v,i);
if(correct)
cmf.Write(&i,sizeof(float));
break;
}
case CHAR_TYPE:
{
int lp=pattern->at[i].length;//已经不包括'/0'
int l=v.GetLength();
if(l<lp)//字符串长度不够
for(int i=0;i<lp-l;i++)
v+='\0';
CString s=v.Left(lp);
char end='\0';
cmf.Write(LPCTSTR(s), lp);
cmf.Write(&end,sizeof(char));//要写/0 ??????????????????????????//???
break;
}
case VARCHAR_TYPE:
{
/////////// 6abcde!!!!'/0' //////////////////////////////////////////
CString s("");
int lp=pattern->at[i].length;//已经不包括/0
int l=v.GetLength();
if(l<lp)//字符串长度不够
for(int i=0;i<lp-l;i++)
v+='\0';
s=v.Left(lp);
if(l>lp)
l=lp;
BYTE len=l+1;//真正长度+1
char end='\0';
cmf.Write(&len,sizeof(BYTE));
cmf.Write(LPCTSTR(s),lp);
cmf.Write(&end,sizeof(char));//要写/0 ??????????????????????????//???
break;
}
case DATE_TYPE:
{
char end='\0';
Date d(v);
CString ds=d.DateToCString();
cmf.Write(LPCTSTR(ds),pattern->at[i].length-1);
cmf.Write(&end,sizeof(char));//要写/0 ??????????????????????????//???
break;
}
case TIME_TYPE:
{
char end='\0';
Time t(v);
CString ts=t.TimeToCString();
cmf.Write(LPCTSTR(ts),pattern->at[i].length-1);
cmf.Write(&end,sizeof(char));//要写/0 ??????????????????????????//???
break;
}
default:
{
//什么都不是
break;
}
}
return correct;
}
UINT Record::GetHalfLength(WORD &half_attr_num)
{
UINT half=UINT(m_length/2);
UINT l=0;
int i=0;
WORD dltalen;
do
{
++i;
if(pattern->at[i].type==CHAR_TYPE)
dltalen=pattern->at[i].length+1;
else if(pattern->at[i].type==VARCHAR_TYPE)
dltalen=pattern->at[i].length+2;
else
dltalen=pattern->at[i].length;
l+=dltalen;
if(l>half)
{
half_attr_num=(half+dltalen-l)<=(l-half) ? i-1 : i;
l=(half+dltalen-l)<=(l-half) ? (l-dltalen) : l;
return l;
}
else if(l==half)
{
half_attr_num=i;
return l;
}
}
while(l<half);
}
Record::~Record()
{
delete []body;
}
CString Record::AttrToString(WORD pos,Relationship *pR1,Relationship *pR2)
{
CMemFile cmf;
CString s;
cmf.Attach(this->body,this->m_length);
UINT uOffset=0;
BYTE type=0;
WORD length=0;
if(!pR1 && !pR2)
{
uOffset=pattern->at[pos].offset;
type=pattern->at[pos].type;
length=pattern->at[pos].length;
}
else
{
if(pos>=1 && pos<=pR1->attr_num)
{
uOffset=pR1->at[pos].offset;
type=pR1->at[pos].type;
length=pR1->at[pos].length;
}
else if(pos>pR1->attr_num)
{
uOffset=pR1->at[pR1->attr_num].offset;
if(pR1->at[pR1->attr_num].type==CHAR_TYPE)
uOffset+= (pR1->at[pR1->attr_num].length+1);
else if(pR1->at[pR1->attr_num].type==VARCHAR_TYPE)
uOffset+= (pR1->at[pR1->attr_num].length+2);
else
uOffset+=pR1->at[pR1->attr_num].length;
uOffset+=pR2->at[pos-pR1->attr_num].offset;
type=pR2->at[pos-pR1->attr_num].type;
length=pR2->at[pos-pR1->attr_num].length;
}
}
cmf.Seek(uOffset,CFile::begin);
switch(type)
{
case INT_TYPE:
{
int ival;
cmf.Read(&ival,sizeof(int));
s.Format("%d",ival);
break;
}
case FLOAT_TYPE:
{
float fval;
cmf.Read(&fval,sizeof(float));
s.Format("%f",fval);
break;
}
case CHAR_TYPE:
{
char * chval=new char[length+1];
cmf.Read(chval,length+1 );
s=CString(chval);
delete []chval;
break;
}
case VARCHAR_TYPE:
{
BYTE len;
cmf.Read(&len,sizeof(BYTE));
char *vchval=new char[len];
cmf.Read(vchval,len);
s=CString(vchval);
delete []vchval;
break;
}
case TIME_TYPE:
case DATE_TYPE:
{
char *val=new char[length];
cmf.Read(val,length);
s=CString(val);
delete []val;
break;
}
default:break;
}
cmf.Detach();
return s;
}
ANY Record::AttrToValue(WORD pos)
{
CMemFile cmf;
ANY value;
value.type=pattern->at[pos].type;
cmf.Attach(this->body,this->m_length);
cmf.Seek(pattern->at[pos].offset,CFile::begin);
switch(pattern->at[pos].type)
{
case INT_TYPE:
cmf.Read(&value.ival,sizeof(int));
break;
case FLOAT_TYPE:
cmf.Read(&value.fval,sizeof(float));
break;
case CHAR_TYPE:
{
char * chval=new char[(pattern->at[pos].length)+1 ];
cmf.Read(chval,(pattern->at[pos].length)+1 );
value.pcval=new CString(chval);
delete []chval;
break;
}
case VARCHAR_TYPE:
{
BYTE len;
cmf.Read(&len,sizeof(BYTE));
char *vchval=new char[len];
cmf.Read(vchval,len);
value.pcval=new CString(vchval);
delete []vchval;
break;
}
case TIME_TYPE:
{
CString s;
char *val=new char[pattern->at[pos].length];
cmf.Read(val,pattern->at[pos].length);
s=CString(val);
value.ptval=new Time(s);
delete []val;
break;
}
case DATE_TYPE:
{
CString s;
char *val=new char[pattern->at[pos].length];
cmf.Read(val,pattern->at[pos].length);
s=CString(val);
value.pdval=new Date(s);
delete []val;
break;
}
default:break;
}
cmf.Detach();
return value;
}
void Record::Update(const CUpdate &update)//改变time
{
WORD i;
CMemFile cmf;
WORD AttrNo=0;
CString value;
cmf.Attach(this->body,this->m_length);
for(i=0;i<update.current;i++)
{
AttrNo=update.up_itms[i].index;
value=update.up_itms[i].value;
cmf.Seek(pattern->at[AttrNo].offset,CFile::begin);
switch(pattern->at[AttrNo].type)
{
case INT_TYPE:
{
int ival=atoi(LPCTSTR(value));
cmf.Write(&ival,sizeof(int));
break;
}
case FLOAT_TYPE:
{
float fval=float(atof(LPCTSTR(value)));
cmf.Write(&fval,sizeof(float));
break;
}
case CHAR_TYPE:
{
int lp=pattern->at[AttrNo].length;//已经不包括'/0'
int l=value.GetLength();
if(l<lp)//字符串长度不够
for(int i=0;i<lp-l;i++)
value+='\0';
CString s=value.Left(lp);
char end='\0';
cmf.Write(LPCTSTR(s), lp);
cmf.Write(&end,sizeof(char));//要写\0 ??????????????????????????//???
break;
}
case VARCHAR_TYPE:
{
/////////// 6abcde!!!!'/0' //////////////////////////////////////////
CString s("");
int lp=pattern->at[AttrNo].length;//已经不包括/0
int l=value.GetLength();
if(l<lp)//字符串长度不够
for(int i=0;i<lp-l;i++)
value+='\0';
s=value.Left(lp);
if(l>lp)
l=lp;
BYTE len=l+1;//真正长度+1
char end='\0';
cmf.Write(&len,sizeof(BYTE));
cmf.Write(LPCTSTR(s),lp);
cmf.Write(&end,sizeof(char));//要写\0 ??????????????????????????//???
break;
}
case TIME_TYPE:
{
char end='\0';
Time t(value);
CString ts=t.TimeToCString();
cmf.Write(LPCTSTR(ts),pattern->at[AttrNo].length-1);
cmf.Write(&end,sizeof(char));//要写/0 ??????????????????????????//???
break;
}
case DATE_TYPE:
{
char end='\0';
Date d(value);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -