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

📄 appdb.c

📁 一个操作系统源代码 用于嵌入式设备 在Vc++环境下仿真 成功移植到多款处理器上
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************
*
* Copyright  2002 National ASIC Center, All rights Reserved
*
* FILE NAME:			appdb.c
* PROGRAMMER:			longn_qi
* Date of Creation:		2002/08/12
* 
* DESCRIPTION: 			This source file defines all operation funtions for 
*						the application layer of the mini-database.
*
* NOTE:			 		 
*						 
* FUNCTIONS LIST:
* -------------------------------------------------------------------------
* CreateDataBase
* InitDataBase
* LinkDataBase
* DetachDataBase
* LocalReadRecord
* LocalModifyRecord
* LocalAddRecord
* LocalDelRecord
* LocalFindRecord
* LocalSearchRecord
*
* GLOBAL VARS LIST:
* 
**************************************************************************
*
* MODIFICATION HISTORY
*
* 2002/08/12	by longn_qi		Create the file
*								
*************************************************************************/
//#include <string.h>
//#include <sys\lmalloc.h>

//#include "appdb.h"
//#include "carddb.h"
//#include "phonehdb.h"
//#include "SMShdb.h"

#include <database\appdb.h>
#include <database\carddb.h>
#include <database\phonehdb.h>
#include <database\SMShdb.h>
#include <database\ntpaddb.h>
#include <database\schemedb.h>
#include <database\emaildb.h>
#include <database\common.h>

#include <sys\sysdebug.h>

static DWORD RewriteDBFile( WORD count, DBPHYLAYERINFO *info, CHECKDBINDEX *checkdbindex );
static DWORD CheckBaseDate( DBGACB *gacb );

extern long GetFileLength( FILE *fp );


// 应用数据库描述
DBDESCRIPTION	DBDescript[DATA_BASE_NUM] = {
				// “名片”应用数据库
				{
#ifdef	SIM_ON_PC					
					"card.db",
#else
					"/db1/card.db",
#endif
					InitCardDB,
					LinkCardDB,
					DetachCardDB,
					CardDBReadRecord,
					CardDBModifyRecord,
					CardDBAddRecord,
					CardDBDelRecord,
					CardDBFindRecord,
					CardDBSortRecord,
					CardDBSortList,
				},
				// “电话历史记录”应用数据库
				{
#ifdef	SIM_ON_PC					
					"phoneh.db",
#else
					"/db3/phoneh.db",
#endif
					InitPhoneHDB,
					LinkPhoneHDB,
					DetachPhoneHDB,
					PhoneHDBReadRecord,
					PhoneHDBModifyRecord,
					PhoneHDBAddRecord,
					PhoneHDBDelRecord,
					PhoneHDBFindRecord,
					PhoneHDBSortRecord,
					PhoneHDBSortList,
				},
				// “短信历史记录”应用数据库
				{
#ifdef	SIM_ON_PC					
					"SMSh.db",
#else
					"/db3/SMSh.db",
#endif
					InitSMSHDB,
					LinkSMSHDB,
					DetachSMSHDB,
					SMSHDBReadRecord,
					SMSHDBModifyRecord,
					SMSHDBAddRecord,
					SMSHDBDelRecord,
					SMSHDBFindRecord,
					SMSHDBSortRecord,
					SMSHDBSortList,
				},
				// “记事本”应用数据库
				{
#ifdef	SIM_ON_PC					
					"notepad.db",
#else
					"/db2/notepad.db",
#endif
					InitNotepadDB,
					LinkNotepadDB,
					DetachNotepadDB,
					NotepadDBReadRecord,
					NotepadDBModifyRecord,
					NotepadDBAddRecord,
					NotepadDBDelRecord,
					NotepadDBFindRecord,
					NotepadDBSortRecord,
					NotepadDBSortList,
				},
				// “电子邮件”应用数据库
				{
#ifdef	SIM_ON_PC					
					"email.db",
#else
					"/db4/email.db",
#endif
					InitEmailDB,
					LinkEmailDB,
					DetachEmailDB,
					EmailDBReadRecord,
					EmailDBModifyRecord,
					EmailDBAddRecord,
					EmailDBDelRecord,
					EmailDBFindRecord,
					EmailDBSortRecord,
					EmailDBSortList,
				},
				// “约会提醒”应用数据库
				{
#ifdef	SIM_ON_PC					
					"scheme.db",
#else
					"/db2/scheme.db",
#endif
					InitSchemeDB,
					LinkSchemeDB,
					DetachSchemeDB,
					SchemeDBReadRecord,
					SchemeDBModifyRecord,
					SchemeDBAddRecord,
					SchemeDBDelRecord,
					SchemeDBFindRecord,
					SchemeDBSortRecord,
					SchemeDBSortList,
				},

			};



// 全局访问控制块
DBGACB			GAcb[DATA_BASE_NUM];

/****************************************************************/
// 功能:创建数据库文件,初始化所有的全局访问控制块
//void CreateDataBase( void )
DWORD CreateDataBase( void )
{
	int		i;
	FILE	*fp;
	const DWORD	head = 0;
	DWORD	result = 0, rv;

	for( i = 0; i < DATA_BASE_NUM; i++ )
	{
		// 根据数据库描述信息创建所有的数据库文件
		fp = fopen( DBDescript[i].path, "rb+" );
		if( fp == NULL )	// 数据库文件未创建
		{
			fp = fopen( DBDescript[i].path, "wb+" );
			if( fp != NULL )
			{
				// 在数据库文件中只有有效记录块的首地址(UBH)一项,其初始值为0
				fwrite( &head, 4, 1, fp );

				// 初始化所有的全局访问控制块为0
				memset( &GAcb[i], 0, sizeof(DBGACB) );
				GAcb[i].funcs = &DBDescript[i].funcs;
				result = DB_OK;
				fclose( fp );
			}else{
				result |= ( 1 << i );
			}
		}else{	// 数据库文件已创建
			// 初始化所有的全局访问控制块为0
			memset( &GAcb[i], 0, sizeof(DBGACB) );

			GAcb[i].funcs = &DBDescript[i].funcs;
			if( ( GAcb[i].PLInfo = ( DBPHYLAYERINFO * )SysLmalloc( sizeof( DBPHYLAYERINFO) ) ) == NULL )
				return DB_ERROR;
			GAcb[i].PLInfo->fp = fp;
			GAcb[i].symbol = DB_SYMBOL;	//数据库结构标识符
			
			fread( &GAcb[i].PLInfo->info.usedBlockHead, HEAD_ADDRESS_BYTE_NUM, 1, fp );// 获取第一条记录的首地址

			rv = CheckBaseDate( &GAcb[i] );
			if( rv == DB_FILE_ERROR )
			{
				result |= ( 1 << i );
			}else{
				result = DB_OK;
			}
			fclose( fp );
		}
	}
//	return;
	return result;
}

/****************************************************************/
// 功能:构建指定数据库的全局访问控制块(在第一次连接数据库时被调用)
DBGACB* InitDataBase( BYTE id )
{
	DBGACB	*gacb;
	FILE	*fp;

	// 验证数据库ID的有效性
	if( id >= DATA_BASE_NUM )
		return NULL;
	
	gacb = &GAcb[id];// 获取该数据库的全局访问控制块(DBGACB)

	// 打开相关联的数据库文件
	fp = fopen( DBDescript[id].path, "rb+" );
	if( fp == NULL )
		return NULL;
	if( ( gacb->PLInfo = ( DBPHYLAYERINFO * )SysLmalloc( sizeof( DBPHYLAYERINFO) ) ) == NULL )
		return NULL;
	gacb->PLInfo->fp = fp;

	gacb->symbol = DB_SYMBOL;	//数据库结构标识符

	fread( &gacb->PLInfo->info.usedBlockHead, HEAD_ADDRESS_BYTE_NUM, 1, fp );// 获取第一条记录的首地址
	
	return gacb->funcs->initDataBase( gacb );// 用局部方法初始化数据库
}

/****************************************************************/
// 功能:连接指定数据库
DBLACB* LinkDataBase( BYTE id )
{
	DBGACB	*gacb, *rv;
	DBLACB	*lacb;

	// 验证数据库ID的有效性;
	if( id >= DATA_BASE_NUM )
		return NULL;

	gacb = &GAcb[id];// 获取该数据库的全局访问控制块(DBGACB)

	// 根据全局访问控制块的访问控制信息判断
	if( gacb->link == 0 )//第一次连接
	{
		dbdbgprintf( "### Initial DataBase ###" );
		rv = InitDataBase( id );		//调用InitDataBase构建该数据库的全局访问控制块
		dbdbgprintf( "### Initial DataBase OK ###" );
		if( rv == NULL ) 
			return NULL;
	}else{
#ifndef	SIM_ON_PC
		fopen( DBDescript[id].path, "rb+" );
#endif
	}

	// 用局部方法连接数据库
	dbdbgprintf( "### Link DataBase ###" );
	lacb = gacb->funcs->linkDataBase( gacb );
	dbdbgprintf( "### Link DataBase OK ###" );
	if( lacb == NULL )	// 连接失败
		return NULL;
	
	gacb->link++;	// 更新访问控制信息
	
	return lacb;
}

/****************************************************************/
// 功能:关闭与指定数据库的连接
DWORD DetachDataBase( DBLACB *lacb )
{
	WORD			i, j, k;
	RECORDINDEX		*temp_record, *temp_record_index;
	FIELDVALUEINDEX *temp_field_value, *temp_field_value_index;
	FIELDINDEX		*I_index_list, *II_index_list;		//字段一二级索引

	//验证指定数据库连接的有效性
	if( lacb == NULL )
		return DB_ERROR;

	if( lacb->gacb->symbol != DB_SYMBOL )
		return DB_ERROR;
		
	dbdbgprintf( "### Detach DataBase ###" );

	lacb->gacb->link--;//更新访问控制信息
	
	//用局部方法切断与数据库连接,释放局部查找表
//	lacb->gacb->funcs->detachDataBase( lacb );

	//根据访问控制信息判断
	if( lacb->gacb->link == 0 ) //已无连接
	{
		fclose( lacb->gacb->PLInfo->fp ); //关闭数据库
		
		//释放所有资源
		for( i = 0; i < lacb->gacb->IFNum; i++ )	//释放字段索引表
		{
			I_index_list = lacb->gacb->FList[i].head;
			for( j = 0; j < lacb->gacb->FList[i].num; j++ )
			{
				if( lacb->gacb->FList[i].level == II_LEVEL )	//字段有两级索引表
				{
					II_index_list = I_index_list->sub;
					for( k = 0; k < I_index_list->num; k++ )
					{
						if( II_index_list != NULL )
						{
							temp_record_index = II_index_list->next;
							while( temp_record_index != NULL )
							{
								temp_record = temp_record_index;
								temp_record_index = temp_record->next;
								SysLfree( temp_record );	//释放记录字段表
							}
						}
						II_index_list++;
					}
					if( I_index_list->sub != NULL )
						SysLfree( I_index_list->sub );		//释放字段索引表的二级索引表
				}
				else if( lacb->gacb->FList[i].level == I_LEVEL )	//字段有一级索引表
				{									
					if( I_index_list != NULL )
					{
						temp_record_index = I_index_list->next;
						while( temp_record_index != NULL )
						{
							temp_record = temp_record_index;
							temp_record_index = temp_record->next;
							SysLfree( temp_record );	//释放记录字段表
						}
					}
				}
				I_index_list++;
			}
		}

		for( i = 0; i < RECORD_FIELD_LIST_LEN; i++ )//释放记录字段表
		{
			if( lacb->gacb->RFList[i] != NULL )
			{
				for( j = 0; j < RECORD_FIELD_LIST_LEN; j++ )//释放记录字段表
				{
					temp_record = lacb->gacb->RFList[i][j];	//二级索引所链接的记录字段的表头
					while( temp_record != NULL )
					{
						temp_record_index = temp_record;
						temp_record = temp_record_index->next;
						temp_field_value = temp_record_index->head;
						while( temp_field_value != NULL )
						{
							temp_field_value_index = temp_field_value;
							temp_field_value = temp_field_value->next;
							SysLfree( temp_field_value_index );	//释放字段值索引表
						}
						SysLfree( temp_record_index );			//释放记录索引表
					}
				}
				SysLfree( lacb->gacb->RFList[i] );
			}
		}
		SysLfree( lacb->gacb->PLInfo );
	}else{
#ifndef	SIM_ON_PC					
		fclose( lacb->gacb->PLInfo->fp ); //关闭数据库
#endif
	}

	SysLfree( lacb );		//释放lacb
	dbdbgprintf( "### Detach DataBase OK ###" );
	return DB_OK;
}

/****************************************************************/
// 功能:从指定数据库读取指定记录的内容

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -