📄 database.c
字号:
#include <pr2k.h>
#include <sys\syscall.h>
#include <Database.h>
//#include <fatSys.h>
#include <filesys.h>
#include <stdio.h>
#include <uiUtility.h>
#define dbEnterWCS enterKernelCriticalSection
#define dbExitWCS exitKernelCriticalSection
#define DB_BUFFER_SIZE 8192 // 数据库系统缓冲区大小
// 全局变量
DB_Database gDatabase[_DB_DBD_MAX]; // 每个Database的结构
int gDbd_IsInit = 0; // Database系统是否已经初始化标志
unsigned char gDbBuffer[DB_BUFFER_SIZE]; //数据库系统缓冲区
// 对齐方式
#ifdef __WIN32__
#define DB_ALGIN2 0x01 // 2Bytes长度的变量
#define DB_ALGIN4 0x01 // 4或8Bytes长度的变量
#else
#define DB_ALGIN2 0x01 // 2Bytes长度的变量
#define DB_ALGIN4 0x03 // 4或8Bytes长度的变量
#endif
// 初始化Database系统,OK
int db_initDatabaseSys(void)
{
int i;
if(gDbd_IsInit)
return _DB_OK; // Database系统已经被初始化
for(i=0;i<_DB_DBD_MAX;i++)
gDatabase[i].hFile = -1; // 每个Database均没有被打开
gDbd_IsInit = 1; // 已经初始化标志
return _DB_OK;
}
// 打开一个Database,OK
int db_open(char *dbdFileName, char *dbdPath, char *dbfPath)
{
int hFile,hDatabase,hmem,bexist=0;
int offset,fileLen,recordTotal,recordNum,recordSize,flag,len;
DB_Head tHead;
DB_Field *pField;
unsigned char *pRecord,*pDelete,*pHead;
int n,num,pos;
int j,i;
int count1,count2;
unsigned char delFlag;
char strdb[20];
if( dbdFileName==NULL || dbdFileName[0] == '\0')
return _DB_NAME_ERROR; // 文件名错误
//myh2002-08-19 initialize the database system!
if(gDbd_IsInit != 1)
db_initDatabaseSys();
dbEnterWCS();
for(hDatabase=0;hDatabase<_DB_DBD_MAX;hDatabase++) // 是否可以再打开一个Database
if( gDatabase[hDatabase].hFile<0 )
break;
if(hDatabase==_DB_DBD_MAX)
{
dbExitWCS();
return _DB_TOO_MUCH; // 打开的数据库太多
}
memset(strdb,0,sizeof(strdb));
strcpy(strdb,dbdFileName);
strcat(strdb,".DBD");
hFile = fs_open((char*)strdb,O_RDWR); // 打开文件
if( hFile<0 )
{
dbExitWCS();
return _FS_ERROR; // 打开文件错误
}
if( fs_read(hFile,(char *)&tHead,sizeof(struct tagHead))!=sizeof(struct tagHead) ) // 读出数据库头信息
{
fs_close(hFile);
dbExitWCS();
return _FS_ERROR; // 读文件错误
}
pHead=(unsigned char*)&tHead;
if(*pHead==0xBB)//myh
bexist=1;
if(bexist)
{
strcpy(strdb,dbdFileName);
strcat(strdb,".MEM");
hmem=fs_open((char*)strdb,O_RDWR);
if( hmem<0 )
{
dbExitWCS();
fs_close(hFile);
return _FS_ERROR;
}
}
pField=(DB_Field *)ap_malloc(sizeof(struct tagField)*(tHead.fieldNum));// 字段信息存储空间
if( !pField )
{
fs_close(hFile);
fs_close(hmem);
dbExitWCS();
return _DB_MEMORY; // 没有足够的内存
}
len=sizeof(struct tagField)*(tHead.fieldNum);
if( fs_read(hFile,(unsigned char *)pField,len)!=len ) // 读出数据库字段信息
{
ap_free(pField);
fs_close(hFile);
fs_close(hmem);
dbExitWCS();
return _FS_ERROR; // 读文件错误
}
recordSize=tHead.recordSize;
pRecord=(unsigned char *)ap_malloc( recordSize ); // 记录存储缓冲区
if( !pRecord )
{
ap_free(pField);
fs_close(hFile);
fs_close(hmem);
dbExitWCS();
return _DB_MEMORY; // 没有足够的内存
}
offset=sizeof(struct tagField)*(tHead.fieldNum)+sizeof(struct tagHead)+1; // 数据区开始位置
fileLen=fs_filelength(hFile); // 文件长度
if( fileLen<offset )
{
ap_free(pField);
ap_free(pRecord);
fs_close(hFile);
fs_close(hmem);
dbExitWCS();
return _FS_ERROR; // 没有足够的内存
}
pDelete=(unsigned char *)ap_malloc( 4096 ); // 记录信息存储缓冲
if( !pDelete )
{
ap_free(pField);
ap_free(pRecord);
fs_close(hFile);
fs_close(hmem);
dbExitWCS();
return _DB_MEMORY; // 没有足够的内存
}
recordTotal=(fileLen-offset)/recordSize; // 物理记录数
recordNum=0; // 有效记录数
gDatabase[hDatabase].curRecord=-1; // 当前记录
gDatabase[hDatabase].curPosition=-1;
flag=1;
if( fs_lseek(hFile,offset,SEEK_SET)<0 ) // 定位在数据区开始
{
ap_free(pRecord);
ap_free(pField);
fs_close(hFile);
fs_close(hmem);
dbExitWCS();
return _FS_ERROR; // 文件错误
}
num=DB_BUFFER_SIZE/recordSize; // 缓冲区中可暂存的记录数
count1=0;
count2=0;
delFlag=0;
for(i=0;i<recordTotal;)
{
n=recordTotal-i;
if(n>num) // 缓冲区中实际暂存的记录数
n=num;
len=n*recordSize;
if( fs_read(hFile,gDbBuffer,len)!=len ) // 读出数据到缓冲区
{
ap_free(pRecord);
ap_free(pField);
ap_free(pRecord);
fs_close(hFile);
fs_close(hmem);
dbExitWCS();
return _FS_ERROR; // 文件错误
}
pos=recordSize-1;
for(j=0;j<n;j++,i++)
{
delFlag<<=1;
if( gDbBuffer[pos]==DB_REC_NORMAL ) // 记录是否有效
{
recordNum++; // 有效记录数加1
if( flag )
{
gDatabase[hDatabase].curRecord=0; // 当前记录信息
gDatabase[hDatabase].curPosition=i;
flag=0;
}
delFlag|=0x01;
}
pos+=recordSize;
count2++;
if(count2==8)
{
pDelete[count1]=delFlag;
count2=0;
delFlag=0;
count1++;
}
}
}
if( count2 )
{
delFlag<<=8-count2;
pDelete[count1]=delFlag;
}
gDatabase[hDatabase].pField=pField; // 字段信息
gDatabase[hDatabase].pRecord=pRecord; // 记录缓冲区
gDatabase[hDatabase].pDelete=pDelete; // 删除标记缓冲区
gDatabase[hDatabase].recordTotal=recordTotal; // 记录总数
gDatabase[hDatabase].recordNum=recordNum;
gDatabase[hDatabase].recordSize=recordSize; // 记录大小
gDatabase[hDatabase].fieldNum=tHead.fieldNum; // 字段数
gDatabase[hDatabase].offset=offset; // 数据区起始位置
gDatabase[hDatabase].error=_DB_CORRECT; // 最后发生的错误
gDatabase[hDatabase].hFile=hFile; // 文件句柄
if(bexist)
{
gDatabase[hDatabase].bexist=bexist;//myh
gDatabase[hDatabase].hmem=hmem;
}
dbExitWCS();
return hDatabase;
}
// 关闭数据库,OK
int db_close(int databaseID)
{
if( (databaseID<0) || (databaseID>=_DB_DBD_MAX) )
return _DB_ID_ERROR; // 数据库句柄无效
if( gDatabase[databaseID].hFile<0)
return _DB_ID_ERROR; // 文件句柄无效
//fs_flush(gDatabase[databaseID].hFile );
fs_close( gDatabase[databaseID].hFile ); // 关闭文件
if(gDatabase[databaseID].bexist==1)
{
//fs_flush(gDatabase[databaseID].hmem );
fs_close(gDatabase[databaseID].hmem);//myh
}
ap_free( gDatabase[databaseID].pField ); // 释放存储空间
ap_free( gDatabase[databaseID].pRecord );
ap_free( gDatabase[databaseID].pDelete );
gDatabase[databaseID].hFile=-1;
return _DB_CORRECT;
}
// 解码一条记录,OK
int _db_decodeRecord(int databaseID,void *buffer)
{
int fieldNum;
int i,j,offset,len,offmem;
short ibuf=0;
unsigned char *pRecord;
unsigned char *pBuffer;
unsigned char *pbuff;
double drecord;
DB_Field *pField;
fieldNum=gDatabase[databaseID].fieldNum; // 字段数
pRecord =gDatabase[databaseID].pRecord; // 记录内容存储区
pField =gDatabase[databaseID].pField; // 字段信息结构
offset=0;
pBuffer=(unsigned char *)buffer; // buffer转为字符型,便于移动指针
for(i=0;i<fieldNum;i++) // 字段逐个解码
{
switch(pField[i].type)
{
case TY_CHAR: // 字符型
case TY_UCHAR:
len=pField[i].size;
for(j=0;j<len;j++)
{
*pBuffer++=*pRecord++;
offset++;
}
if(len!=1) // len>1时表示为字符串
{
*pBuffer='\0'; // 字符串结尾补0
pBuffer++;
offset++;
}
break;
case TY_SHORT: // 短整型
case TY_USHORT:
while(1)
{
if( !(offset&DB_ALGIN2) ) // 对齐
break;
offset++;
pBuffer++;
}
*pBuffer++=*pRecord++;
*pBuffer++=*pRecord++;
offset+=2;
break;
case TY_INT: // 整型和长整型
case TY_LONG:
case TY_UINT:
case TY_ULONG:
case TY_FLOAT: // 浮点型
while(1)
{
if( !(offset&DB_ALGIN4) ) // 对齐
break;
offset++;
pBuffer++;
}
*pBuffer++=*pRecord++;
*pBuffer++=*pRecord++;
*pBuffer++=*pRecord++;
*pBuffer++=*pRecord++;
offset+=4;
break;
case TY_VARCHAR: //varchar
memcpy(&offmem,pRecord,4);
pRecord+=4;
memcpy(&ibuf,pRecord,2);
pRecord+=2;
pbuff=(unsigned char*)ap_malloc(pField[i].other);
memset(pbuff,0,pField[i].other);
fs_lseek(gDatabase[databaseID].hmem,offmem,0);
fs_read(gDatabase[databaseID].hmem,pbuff,ibuf);
memcpy(pBuffer,pbuff,pField[i].other);
pBuffer+=pField[i].other;
offset+=pField[i].other;
ap_free(pbuff);
break;
case TY_VARBYTE: //varbyte
memcpy(&offmem,pRecord,4);
pRecord+=4;
memcpy(&ibuf,pRecord,2);
pRecord+=2;
pbuff=(unsigned char*)ap_malloc(pField[i].other);
memset(pbuff,0,pField[i].other);
fs_lseek(gDatabase[databaseID].hmem,offmem,0);
fs_read(gDatabase[databaseID].hmem,pbuff,ibuf);
memcpy(pBuffer,pbuff,pField[i].other);
pBuffer+=pField[i].other;
offset+=pField[i].other;
ap_free(pbuff);
break;
case TY_DOUBLE: // 双精度型
while(1)
{
if( !(offset&DB_ALGIN4) ) // 对齐
break;
offset++;
pBuffer++;
}
*pBuffer++=*pRecord++;
*pBuffer++=*pRecord++;
*pBuffer++=*pRecord++;
*pBuffer++=*pRecord++;
*pBuffer++=*pRecord++;
*pBuffer++=*pRecord++;
*pBuffer++=*pRecord++;
*pBuffer++=*pRecord++;
offset+=8;
break;
default:
return _DB_ELSE_ERROR; // 其它类型时说明发生错误
}
}
return _DB_CORRECT;
}
// 编码一条记录,OK
int _db_encodeRecord(int databaseID,void *buffer)
{
int fieldNum;
int i,j,offset,len,offmem;
short ibuf=0;
unsigned char *pRecord;
unsigned char *pBuffer;
unsigned char *pbuff;
DB_Field *pField;
fieldNum=gDatabase[databaseID].fieldNum;
pRecord =gDatabase[databaseID].pRecord;
pField =gDatabase[databaseID].pField;
offset=0;
pBuffer=(unsigned char *)buffer; // buffer转为字符型,便于移动指针
for(i=0;i<fieldNum;i++) // 字段逐个解码
{
switch(pField[i].type)
{
case TY_CHAR: // 字符型
case TY_UCHAR:
len=pField[i].size;
for(j=0;j<len;j++)
{
*pRecord++=*pBuffer++;
offset++;
}
if(len!=1) // len>1时表示为字符串
{
offset++; // 跳过结尾的'\0'
pBuffer++;
}
break;
case TY_SHORT: // 短整型
case TY_USHORT:
while(1)
{
if( !(offset&DB_ALGIN2) ) // 对齐
break;
offset++;
pBuffer++;
}
*pRecord++=*pBuffer++;
*pRecord++=*pBuffer++;
offset+=2;
break;
case TY_INT: // 整型和长整型
case TY_LONG:
case TY_UINT:
case TY_ULONG:
case TY_FLOAT: // 浮点型
while(1)
{
if( !(offset&DB_ALGIN4) ) // 对齐
break;
offset++;
pBuffer++;
}
*pRecord++=*pBuffer++;
*pRecord++=*pBuffer++;
*pRecord++=*pBuffer++;
*pRecord++=*pBuffer++;
offset+=4;
break;
case TY_VARCHAR: //varchar
offmem=fs_filelength(gDatabase[databaseID].hmem);
fs_lseek(gDatabase[databaseID].hmem,offmem,0);
pbuff=(unsigned char*)ap_malloc(pField[i].other+1);
memset(pbuff,0,pField[i].other+1);
memcpy(pbuff,pBuffer,pField[i].other);
ibuf=strlen((char*)pbuff);
fs_write(gDatabase[databaseID].hmem,pbuff,ibuf);
memcpy(pRecord,&offmem,4);
pRecord+=4;
memcpy(pRecord,&ibuf,2);
pRecord+=2;
pBuffer+=pField[i].other;
offset+=pField[i].other;
ap_free(pbuff);
break;
case TY_VARBYTE: //varbyte
offmem=fs_filelength(gDatabase[databaseID].hmem);
fs_lseek(gDatabase[databaseID].hmem,offmem,0);
pbuff=(unsigned char*)ap_malloc(pField[i].other+1);
memset(pbuff,0,pField[i].other+1);
memcpy(pbuff,pBuffer,pField[i].other);
//ibuf=strlen((char*)pbuff);
memcpy(&ibuf,pbuff,sizeof(ibuf));
fs_write(gDatabase[databaseID].hmem,pbuff,ibuf);
memcpy(pRecord,&offmem,4);
pRecord+=4;
memcpy(pRecord,&ibuf,2);
pRecord+=2;
pBuffer+=pField[i].other;
offset+=pField[i].other;
ap_free(pbuff);
break;
case TY_DOUBLE: // 双精度型
while(1)
{
if( !(offset&DB_ALGIN4) ) // 对齐
break;
offset++;
pBuffer++;
}
*pRecord++=*pBuffer++;
*pRecord++=*pBuffer++;
*pRecord++=*pBuffer++;
*pRecord++=*pBuffer++;
*pRecord++=*pBuffer++;
*pRecord++=*pBuffer++;
*pRecord++=*pBuffer++;
*pRecord++=*pBuffer++;
offset+=8;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -