⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 database.c

📁 一个微型的数据库系统
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 + -