📄 db.cpp
字号:
#include "db.h"
char db_header[DB_HEADER_SIZE+1];
/*set teh max record number*/
void db_SetRecNum(int *max_num)
{
int times=0;
int max_rec_num;
printf("input the max record number(0~100):");
scanf("%d",&max_rec_num);
while(!(max_rec_num>0&&max_rec_num<100))
{
printf("invalid range,input again:");
scanf("%d",&max_rec_num);
}
printf("the max record is %d\n",max_rec_num);
*max_num=max_rec_num;
}
/*read the db header's info from db file to db struct*/
/*free_block_num,cur_rec_num or max_rec_num*/
int db_ReadHeader(DB *db,int off_flag)
{
rewind(db->fpdb);
if((fread((char *)db_header,sizeof(char),sizeof(db_header),db->fpdb))!=DB_HEADER_SIZE+1)
{
printf("read data error\n");
return NULL;
}
if(off_flag==FREE_OFF_FLAG)
return ((DB_Header*)db_header)->free_block_num;
else
{
if(off_flag==CUR_OFF_FLAG)
return ((DB_Header*)db_header)->cur_rec_num;
else
return ((DB_Header*)db_header)->max_rec_num;
}
}
/*wirte the db header's info to the db file*/
bool db_SetHeader(DB *db)
{
((DB_Header*)db_header)->cur_rec_num=db->cur_rec_num;
((DB_Header*)db_header)->free_block_num=db->free_block_num;
((DB_Header*)db_header)->max_rec_num=db->max_rec_num;
rewind(db->fpdb);
if( (fwrite((char *)db_header,sizeof(char),sizeof(db_header),db->fpdb))!=DB_HEADER_SIZE+1)
{
printf("write db header error!\n");
return false;
}
fflush(db->fpdb);
return true;
}
/*read all the record from db file to db struct*/
bool db_ReadRecord(DB *db)
{
fseek(db->fpdb,(long)REC_OFF_FLAG,0); //set the fpdb to the first record;
for(int i=0;i<db->cur_rec_num;i++)
{
if( (fread((char *)(&(db->pDB_Rec[i])),sizeof(DB_Rec),1,db->fpdb))!=1)
{
printf("read record error!\n");
return false;
}
}
return true;
}
/*write a record to the db file*/
bool db_WriteRecord(FILE *fp,DB_Rec *prec)
{
if( (fwrite( (char *)prec,sizeof(char),sizeof(DB_Rec),fp))!= DB_REC_SIZE)
{
printf("write record to db error!\n");
return false;
}
else
return true;
}
/*display a special record*/
void db_DisplayRecord(DB *db,int position)
{
char *ptm;
time_t tm;
while(position>db->cur_rec_num||position<0)
{
printf("your input should between 1~%d,please check it\n",db->cur_rec_num);
printf("input again:");
scanf("%d",&position);
}
tm=(time_t)db->pDB_Rec[position-1].time;
ptm=ctime(&tm);
printf("\nrecord[%d]:%s\ttime:%s\n",position,db->pDB_Rec[position-1].data,ptm);
}
//find the index of the min records by time to sort;
int db_FindMin(DB * db)
{
int min=0;
for(int j=1;j<db->cur_rec_num;)
{
if(db->pDB_Rec[min].time<db->pDB_Rec[j].time )
{
j++;
}
else
{
min=j;
j++;
}
}
return min;
}
/* QuickSort
void db_QuickSort(DB_Rec data[],int low ,int high)
{
int i,keyword,j;
if(low<high)
{
keyword=data[low];
i=low;
j=high;
while(i<j) //从数组两端交替的向中间扫描
{
while(i<j&&data[j]>=keyword)
j--;
if(i<j)
data[i++]=data[j];
while(i<j&&data[i]<=keyword)
i++;
if(i<j)
data[j--]=data[i];
}
data[i]=keyword;
QuickSort(data,low,i-1);
quickSort(data,i+1,high);
}
}
*/
/*display all the record*/
void db_DisplayAllRecord(DB *db)
{
int i,j;
int minrectm=db_FindMin(db);
printf("------------------------------------------------------------\n");
for(i=minrectm;i<db->cur_rec_num;i++)
db_DisplayRecord(db,i+1);
for(j=minrectm; j>0;j--)
db_DisplayRecord(db,j);
printf("------------------------------------------------------------\n");
}
/*find a free block ,if no free block return -1 flag to replace the first record*/
int db_GetFreeBlock(DB *db)
{
if(db->free_block_num<=0)
{
printf("no free block,replace the first record!\n");
return -1;
}
else
return db->cur_rec_num;
}
/* judge wheather the record is exist*/
bool db_CompareRecord(DB *db,char *str)
{
int i;
int slen=strlen(str);
for(i=0;i<db->cur_rec_num;i++)
{
char *pstr=db->pDB_Rec[i].data;
if(slen==strlen(pstr))
{
if(strcmp(str,pstr)==0)
{
return false;
}
}
else
continue;
}
return true;
}
/* add a record */
bool db_AddRecord(DB *db,char *strrec)
{
time_t tm;
long recoff;
char *ltm;
int free_num;
free_num=db_GetFreeBlock(db);
if(-1==free_num) /*if -1 means no free block,replace the first record*/
{
tm=time(NULL); /*get the system time*/
db->pDB_Rec[0].time=tm;
strcpy(db->pDB_Rec[0].data,strrec);
}
else
{
/*fseek(db->fpdb,0L,2); point to the last; */
/* recoff=ftell(db->fpdb);*/
/*db->pDB_Rec[free_num].offset=recoff;*/
tm=time(NULL); /*get the system time*/
db->pDB_Rec[free_num].time=tm;
strcpy(db->pDB_Rec[free_num].data,strrec);
db->cur_rec_num++;
db->free_block_num--;
if(false==db_SetHeader(db))
return false;
fflush(db->fpdb);
}
printf("add a record success!\n");
return true;
}
/*modify a special record*/
void db_ModifyRecord(DB *db,int position)
{
char newrecord[MAX_MSG];
time_t tm;
char *ptm;
int len;
while(position>db->cur_rec_num||position<0)
{
printf("your input should between 1~%d,please check it\n",db->cur_rec_num);
printf("input again:");
scanf("%d",&position);
}
printf("please input a new record:");
scanf("%s",newrecord);
while( false==db_CompareRecord(db,newrecord)) /*judge whether the record is exist in db*/
{
printf("the record is exist,can't upload !\n");
printf("input again:");
scanf("%s",newrecord);
}
len=strlen(newrecord);
strcpy(db->pDB_Rec[position-1].data,newrecord);
db->pDB_Rec[position-1].data[len]='\0';
tm=time(NULL); /*get the system time*/
db->pDB_Rec[position-1].time=tm;
printf("modify record[%d] success!\n",position);
ptm=ctime(&tm);
printf("\nrecord[%d]:%s\t time:%s\n",position,db->pDB_Rec[position-1].data, ptm ) ;
}
/*delete a special record */
void db_DeleteRecord(DB *db,int position)
{
int index=position-1;
while(position>db->cur_rec_num||position<0)
{
printf("your input should between 1~%d,please check it\n",db->cur_rec_num);
printf("input again:");
scanf("%d",&position);
}
for(int i=index;i<db->cur_rec_num;i++)
db->pDB_Rec[i]=db->pDB_Rec[i+1]; /*delet one and the remained record move ahead*/
db->cur_rec_num--; /*after that ,easy to sort*/
db->free_block_num++;
}
//delete all the record
void db_DeleteAllRecord(DB *db)
{
int cur_num=db->cur_rec_num;
for(int i=1;i<=cur_num;i++)
db_DeleteRecord(db,1); /*delete the first record all the time*/
printf("delete all record success!\n");
}
/*init db file:create db file,set the max record number*/
/*if the db file is exist,set the oldflag ==true ,use it to read record to db struct*/
bool db_Init(char *filename,bool *flag)
{
FILE *fpdb;
int read_size;
char yn;
int max_rec_num,free_block_num,cur_rec_num;
if( (fpdb=fopen(filename,"rb+"))==NULL) /*the database is not exist*/
{
printf("initilize and create a database......\n");
if( (fpdb=fopen(filename,"wb+"))==NULL)
{
printf("create database error!\n");
return false;
}
db_SetRecNum(&max_rec_num);
}
else /*the database is exist*/
{
printf("the database is exist!\n");
read_size=fread((char *)db_header,sizeof(char),sizeof(db_header),fpdb);
if(read_size<=0) /*not data in the db,so reset the max_rec_num*/
{
db_SetRecNum(&max_rec_num);
}
else /*read the data from db file,ad display it */
{
free_block_num=((DB_Header*)db_header)->free_block_num;
cur_rec_num=((DB_Header*)db_header)->cur_rec_num;
max_rec_num=((DB_Header*)db_header)->max_rec_num;
printf("free_block:%d\tcur_rec_num:%d\tmax_rec_num:%d\n",free_block_num,cur_rec_num,max_rec_num);
printf("Do you want modify the max record number(if yes the data is lost): y/n?");
scanf("%s",&yn);
if(yn=='y') /*modify the max_rec_num*/
{
db_SetRecNum(&max_rec_num);
fclose(fpdb);
if( (fopen(filename,"wb+"))==NULL) /*create a new db file*/
{
printf("can't open db\n");
return false;
}
}
else /*don't modify the max_rec_num*/
{ /*if db is exist ,set the oldflag ==true*/
*flag=true;
goto END;
}
}
}
/*write the db_header's information to db file*/
((DB_Header*)db_header)->free_block_num=max_rec_num;
((DB_Header*)db_header)->max_rec_num=max_rec_num;
((DB_Header*)db_header)->cur_rec_num=0;
rewind(fpdb);
if((fwrite((char *)db_header,sizeof(char),sizeof(db_header),fpdb))!=DB_HEADER_SIZE+1)
{
printf("write db header error!\n");
return false;
}
printf("create %s database success!\n",filename);
fflush(fpdb);
END:fclose(fpdb);
return true;
}
/*base on the exist db file;allocate the memery to db struct*/
DB *db_Open(char *filename,char *mode,bool flag)
{
DB *db;
FILE *fpdb;
int max_rec_num,free_block_num,cur_rec_num;
if( (fpdb=fopen(filename,mode))==NULL)
{
printf("open database error!\n");
exit(0);
}
if((fread((char *)db_header,sizeof(char),sizeof(db_header),fpdb))!=DB_HEADER_SIZE+1)
{
printf("read data error\n");
return NULL;
}
max_rec_num=((DB_Header*)db_header)->max_rec_num;
db=(DB*)calloc(1,sizeof(DB)); /* allocate the memery*/
if(db==NULL)
{
printf( "can't allocate memory for db\n" );
return NULL;
}
db->pDB_Rec=(DB_Rec*)calloc(1,max_rec_num*DB_REC_SIZE);
if(db->pDB_Rec==NULL)
{
printf( "can't allocate memory for record\n" );
return NULL;
} /*initilize db header*/
db->free_block_num=((DB_Header*)db_header)->free_block_num;
db->max_rec_num=((DB_Header*)db_header)->max_rec_num;
db->cur_rec_num=((DB_Header*)db_header)->cur_rec_num;
db->fpdb=fpdb;
printf("open database success!\n");
if(flag==true) /*read the record from db file*/
{
if(false==db_ReadRecord(db))
return NULL;
else
printf("read exist record success!\n");
}
return db;
}
/*close db file*/
bool db_Close(DB *db)
{
if(db->cur_rec_num==0)
{ /*if delete all the record,so create a new db file,no need to read record*/
fclose(db->fpdb);
if( NULL==(db->fpdb=fopen("local_db.db","w+")))
{
printf("create new db failed!\n");
return false;
}
db_SetHeader(db);
}
else /*after close db file,write all the records to the db file*/
for(int i=0;i<db->cur_rec_num;i++)
{ /*always set the fp to the last record*/
fseek(db->fpdb,REC_OFF_FLAG+i*DB_REC_SIZE,0);
if (false==db_WriteRecord(db->fpdb,&(db->pDB_Rec[i])))
return false;
}
fclose(db->fpdb);
free(db);
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -