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

📄 carddb.c

📁 一个操作系统源代码 用于嵌入式设备 在Vc++环境下仿真 成功移植到多款处理器上
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************
*
* Copyright  2002 National ASIC Center, All rights Reserved
*
* FILE NAME:			carddb.c
* PROGRAMMER:			longn_qi
* Date of Creation:		2002/08/12
* 
* DESCRIPTION: 			Database operations for the application "card".
*
* NOTE:			 		 
*						 
*
* FUNCTIONS LIST:
* -------------------------------------------------------------------------
* InitCardDB
* LinkCardDB
* DetachCardDB
* CardDBReadRecord
* CardDBModifyRecord
* CardDBAddRecord
* CardDBDelRecord
* CardDBFindRecord
* CardDBSearchRecord
*
* GLOBAL VARS LIST:
* 
*
**************************************************************************
*
* MODIFICATION HISTORY
*
*
* 2002/08/12	by longn_qi		Create the file
*								
*************************************************************************/
#include <string.h>
#include <sys\lmalloc.h>

#include <database\carddb.h>
#include <database\common.h>

// 字段索引
FIELDINDEX	CARDNameField_I[27];					// 姓名一级索引表
FIELDINDEX	CARDMobileField_I[100];					// 手机一级索引表
FIELDINDEX	CARDPhoneField_I[100];					// 固话一级索引表
FIELDINDEX	CARDRelationField[5];					// 关系索引表
/*
FIELDINDEXLIST	CardDBFList[ CARD_INDEX_FIELD_NUM ] = 
	{
		{	CARD_NAME_FIELD,	SINGLE_VALUE_FIELD,	27,		CARDNameField_I,   II_LEVEL },		// 姓名索引表
		{	CARD_MOBILE_FIELD,	MULTI_VALUE_FIELD,	100,	CARDMobileField_I, II_LEVEL	},		// 手机索引表
		{	CARD_PHONE_FIELD,	MULTI_VALUE_FIELD,	100,	CARDPhoneField_I,  II_LEVEL	},		// 固话索引表
		{	CARD_RELATION_FIELD,SINGLE_VALUE_FIELD,	5,		CARDRelationField, I_LEVEL	}		// 关系索引表
	};
*/
FIELDINDEXLIST	CardDBFList[ CARD_FIELD_NUM ] = 
	{
		{	CARD_NAME_FIELD,	SINGLE_VALUE_FIELD,	27,		CARDNameField_I,   II_LEVEL },		// 姓名索引表
		{	CARD_MOBILE_FIELD,	MULTI_VALUE_FIELD,	100,	CARDMobileField_I, II_LEVEL	},		// 手机索引表
		{	CARD_PHONE_FIELD,	MULTI_VALUE_FIELD,	100,	CARDPhoneField_I,  II_LEVEL	},		// 固话索引表
		{	CARD_RELATION_FIELD,SINGLE_VALUE_FIELD,	5,		CARDRelationField, I_LEVEL	},		// 关系索引表
		{	0,	MULTI_VALUE_FIELD,	0,		NULL,   0 },		
		{	0,	MULTI_VALUE_FIELD,	0,		NULL,   0 },		
		{	0,	MULTI_VALUE_FIELD,	0,		NULL,   0 },		
		{	0,	MULTI_VALUE_FIELD,	0,		NULL,   0 },		
		{	0,	MULTI_VALUE_FIELD,	0,		NULL,   0 },		
		{	0,	MULTI_VALUE_FIELD,	0,		NULL,   0 },		
		{	0,	MULTI_VALUE_FIELD,	0,		NULL,   0 },		
		{	0,	MULTI_VALUE_FIELD,	0,		NULL,   0 }		
	};

//-------------------- Local Functions List --------------------------------------------//
//初始化一级索引表
static void InitIndexList( void );
// 将字段值加入到字段索引表
static DWORD Add2FieldIndexTbl( DBGACB *gacb, BYTE field, BYTE *value, DWORD id );
//创建新的二级索引表
static FIELDINDEX *CreateIIIndexList( FIELDINDEX *I_index_list, BYTE field );
//获取手机号码字段值的一二级索引
static void GetPhoneFieldIandIIIndex( BYTE *field_value, WORD *field_I_index, WORD *field_II_index, BYTE field );

/****************************************************************/
DBGACB* InitCardDB( DBGACB *gacb )
{
	DWORD	id = gacb->PLInfo->info.usedBlockHead;
	BYTE	i;

	InitIndexList();	// 初始化一级字段索引表

	gacb->IFNum = CARD_INDEX_FIELD_NUM;
	gacb->FList = CardDBFList;
	gacb->fieldNum = CARD_FIELD_NUM;
	
	for( i = 0; i < RECORD_FIELD_LIST_LEN; i++)
		gacb->RFList[i] = 0;

	// 构建物理模式信息
	gacb->PLInfo->info.usedBlockTail = 0;
	gacb->PLInfo->info.freeBlockHead = 0;
	gacb->PLInfo->info.usedBlockNum = 0;
	gacb->PLInfo->info.freeBlockNum = 0;

	if( id != 0 )	// 判断记录是否为空
	{
		// 记录不为空
		DBRECORDHEAD	*head_info = NULL;
		BYTE	*record = NULL, *data, *field_value;
#ifdef SIM_ON_PC
		WORD	*field;
#else
		WORD	field;
#endif
		BYTE	i;
		WORD	record_size = 0;
		DWORD	record_num = 0;
		FIELDINDEXLIST	*field_index_list;
		DWORD	rv = DB_OK;

		// 逐条读取记录,建立字段索引表和记录字段表
		do
		{
			rv = GlobalReadRecord( gacb->PLInfo, id, &record );
			if( rv == DB_FREE_RECORD )	//空闲记录
				record = NULL;
			if( ( rv == DB_NO_MEM ) || ( rv == DB_ERROR ) )		
				return NULL;

			if( record == NULL )//空闲记录块
			{
				if( ( head_info = (DBRECORDHEAD *)SysLmalloc(sizeof(DBRECORDHEAD)) ) == NULL )
					return NULL;
				gacb->PLInfo->info.freeBlockHead = id;
				//初始化空闲块数目
				fseek( gacb->PLInfo->fp, id+ADDRESS_BYTE_NUM, SEEK_SET );
				fread( &record_size, SIZE_BYTE_NUM, 1, gacb->PLInfo->fp );
				record_num = (DWORD)( ( record_size + BLOCK_DATA_SIZE - 1 ) / BLOCK_DATA_SIZE );
				gacb->PLInfo->info.freeBlockNum += record_num;
				//初始化尾记录地址
				fseek( gacb->PLInfo->fp, id+ADDRESS_BYTE_NUM+SIZE_BYTE_NUM+FLAG_BYTE_NUM+NEXT_BYTE_NUM, SEEK_SET );
				fread( &head_info->prev, PREV_BYTE_NUM, 1, gacb->PLInfo->fp );
				gacb->PLInfo->info.usedBlockTail = head_info->prev;
				SysLfree( head_info );
				break;
			}else{	//有效记录块
				head_info = (DBRECORDHEAD *)record;

				record_size = head_info->size;
				record_num = (DWORD)( ( record_size + BLOCK_DATA_SIZE - 1 ) / BLOCK_DATA_SIZE );

				gacb->PLInfo->info.usedBlockTail = id;//初始化尾记录地址
				gacb->PLInfo->info.usedBlockNum += record_num;

				data = (BYTE *)(&head_info->data);
#ifdef SIM_ON_PC
				field = (WORD *)data;
#endif

				field_index_list = gacb->FList;
				for( i = 0; i < gacb->IFNum; i++ )
				{
#ifdef SIM_ON_PC
					if( field[i] != 0 )	// 字段有字段值
#else
					Bytes2Word( &field, data+i*sizeof(WORD) );
					if( field != 0 )	// 字段有字段值
#endif
					{
#ifdef SIM_ON_PC
						WORD	next_field_value = field[i]; 
#else
						WORD	next_field_value = field, temp; 
#endif
						while( next_field_value != 0 )
						{
							// 根据字段类型取出字段值
							switch( field_index_list->type )
							{
								case MULTI_VALUE_FIELD:		// 多值字段,带字段值索引
									field_value = data + next_field_value + 2;	// 跳过字段值索引(2字节)
#ifdef SIM_ON_PC
									next_field_value = *(WORD *)( data + next_field_value );
#else
									temp = next_field_value;
									Bytes2Word( &next_field_value, data + temp );
#endif
									break;
								case SINGLE_VALUE_FIELD:	// 单值字段,不带字段值索引
									field_value = data + next_field_value;
									next_field_value = 0;
									break;
							}
							// 将字段值加入到字段索引表				
							Add2FieldIndexTbl( gacb, i, field_value, id );
						}
					}
					field_index_list++;
				}
				id = head_info->next;
				SysLfree( record );
			}
		}while( id != 0 );

	}
	return gacb;
}

/**********************************************************************/
DBLACB* LinkCardDB( DBGACB *gacb )
{
	return LinkDB( gacb );
}

/**********************************************************************/
void DetachCardDB( DBLACB *lacb )
{
	RECORDDATA		*prev_record_data, *next_record_data;

	next_record_data = lacb->head->head;
	while( ( next_record_data != NULL ) && ( lacb->head->num != 0 ) )
	{
		prev_record_data = next_record_data;
		next_record_data++;
		if( prev_record_data->data != NULL )
			SysLfree( prev_record_data->data );
		lacb->head->num--;
	}
	
	SysLfree( lacb->head->head );
	SysLfree( lacb->head );
	return;
}
/**********************************************************************/
BYTE* CardDBReadRecord( DBLACB *lacb, DWORD id )
{
	return ReadDBRecord( lacb, id );
}

/**********************************************************************/
DWORD CardDBModifyRecord( DBLACB *lacb, DWORD id, BYTE *data, WORD dataLen )
{	
	BYTE			i;
	BYTE			*field_value, *record;
#ifdef SIM_ON_PC
	WORD	*field;
#else
	WORD	field;
#endif
	FIELDINDEXLIST	*field_index_list;
	DWORD			rv = DB_OK;

	//读出修改前的数据
	rv = GlobalReadRecord( lacb->gacb->PLInfo, id, &record );
	if( rv != DB_OK )
		return DB_ERROR;

	DelRecordIndexTbl( lacb, id );
	//填充修改后的数据
	id = AddModifiedRecordData( lacb->gacb->PLInfo, id, data, dataLen, record );
	if( id == DB_ERROR )
		return DB_ERROR;

	//把修改后的记录添加大字段索引表和记录字段索引表中
#ifdef SIM_ON_PC
	field = (WORD *)data;
#endif
			
	field_index_list = lacb->gacb->FList;
	for( i = 0; i < lacb->gacb->IFNum; i++ )
	{
#ifdef SIM_ON_PC
		if( field[i] != 0 )	// 字段有字段值
#else
		Bytes2Word( &field, data+i*sizeof(WORD) );
		if( field != 0 )	// 字段有字段值
#endif
		{
#ifdef SIM_ON_PC
			WORD	next_field_value = field[i]; 
#else
			WORD	next_field_value = field, temp; 
#endif
			while( next_field_value != 0 )
			{
				// 根据字段类型取出字段值
				switch( field_index_list->type )
				{
					case MULTI_VALUE_FIELD:		// 多值字段,带字段值索引
						field_value = data + next_field_value + 2;	// 跳过字段值索引(2字节)
#ifdef SIM_ON_PC
						next_field_value = *(WORD *)( data + next_field_value );
#else
						temp = next_field_value;
						Bytes2Word( &next_field_value, data + temp );
#endif
						break;
					case SINGLE_VALUE_FIELD:	// 单值字段,不带字段值索引
						field_value = data + next_field_value;
						next_field_value = 0;
						break;
				}
				// 将字段值加入到字段索引表				
				Add2FieldIndexTbl( lacb->gacb, i, field_value, id );
			}
		}
		field_index_list++;
	}

	return id;
}

/**********************************************************************/
DWORD CardDBAddRecord( DBLACB *lacb, BYTE *data, WORD dataLen )
{
	BYTE			i;
	BYTE			*field_value;
#ifdef SIM_ON_PC
	WORD			*field;
#else
	WORD			field;
#endif
	DWORD			id = 0;
	FIELDINDEXLIST	*field_index_list;

	//填充新添加的数据
	id = AddNewRecordData( lacb->gacb->PLInfo, data, dataLen );
	if( id == DB_ERROR )
		return DB_ERROR;
	
	//把修改后的记录添加大字段索引表和记录字段索引表中
#ifdef SIM_ON_PC
	field = (WORD *)data;
#endif
	field_index_list = lacb->gacb->FList;
			
	for( i = 0; i < lacb->gacb->IFNum; i++ )
	{
#ifdef SIM_ON_PC
		if( field[i] != 0 )	// 字段有字段值
#else
		Bytes2Word( &field, data+i*sizeof(WORD) );
		if( field != 0 )	// 字段有字段值
#endif
		{
#ifdef SIM_ON_PC
			WORD	next_field_value = field[i]; 
#else
			WORD	next_field_value = field, temp; 
#endif
			while( next_field_value != 0 )
			{
				// 根据字段类型取出字段值
				switch( field_index_list->type )
				{
					case MULTI_VALUE_FIELD:		// 多值字段,带字段值索引
						field_value = data + next_field_value + 2;	// 跳过字段值索引(2字节)
#ifdef SIM_ON_PC
						next_field_value = *(WORD *)( data + next_field_value );
#else
						temp = next_field_value;
						Bytes2Word( &next_field_value, data + temp );
#endif
						break;
					case SINGLE_VALUE_FIELD:	// 单值字段,不带字段值索引
						field_value = data + next_field_value;
						next_field_value = 0;
						break;
				}
				Add2FieldIndexTbl( lacb->gacb, i, field_value, id );// 将字段值加入到字段索引表
			}	
		}
		field_index_list++;
	}
	
	return id;
}

/**********************************************************************/
DWORD CardDBDelRecord( DBLACB *lacb, DWORD id )
{
	id = GlobalDelRecord( lacb->gacb->PLInfo, id );			//在数据库中删除指定的记录
	if( ( id == DB_ERROR ) || ( id == DB_FREE_RECORD ) )
		return DB_ERROR;
		
	DelRecordIndexTbl( lacb, id );
	
	return id;

}
/**********************************************************************/
//在指定数据库中查找与指定字段匹配(完全匹配/部分匹配)的记录(精确查找)
LOCALSEARCHLIST* CardDBFindRecord( DBLACB *lacb, BYTE field, BYTE *data, BYTE mode )
{	
	WORD				i, j, k = 0, count = 0;
	CHAR				rv;			//字段值比较结果
	BYTE				*record;	//记录数据
	DBRECORDHEAD		*head_info;
	WORD				record_size = 0, cmp_data_size;
	BYTE				*record_data = NULL, *field_value, *tmp_field_value;
#ifdef SIM_ON_PC
	WORD				*field_head;
#else
	WORD				field_head;
#endif
	FIELDINDEXLIST		*list;		//字段索引表	
	FIELDINDEX			*I_index_list, *II_index_list;	//一、二级索引表
	WORD				field_I_index[PY_MAX_NUM], field_II_index[PY_MAX_NUM];//字段一二级索引值
	RECORDINDEX			*next_record_index; 
	DWORD				tmp_id;		//记录地址
	BYTE				PY_num = 0;
	RECORDINDEX			*local_search_list = NULL;
	RECORDDATA			*record_data_head, *record_head, *next_record_data, *next_record_head;//*prev_record_head, 
	BYTE				flag = 0;
	DWORD				read_rv = DB_OK;

	//验证字段的有效性
	if( field < 0 || field > ( lacb->gacb->IFNum - 1) )
		return NULL;
	
	//验证查找模式的有效性
	if( ( mode != PRECISE_FULL_MATCH ) && ( mode != PRECISE_PART_MATCH ) && ( mode != GLOBAL_SEARCH ) )
		return NULL;

	list = lacb->gacb->FList;
	I_index_list = list[field].head;//找到相符的一级字段索引表

	//申请局部查找表
	if( ( lacb->head = SysLmalloc( sizeof(LOCALSEARCHLIST) ) ) == NULL )	
		return NULL;
	lacb->head->num = 0;
	lacb->head->head = NULL;

	if( ( mode == GLOBAL_SEARCH ) && ( data == NULL ) )		//所有记录按姓名排列
	{
		for( i = 0; i < list[field].num; i++ )
		{
			II_index_list = I_index_list->sub;
			for( j = 0; j < I_index_list->num; j++ )
			{
				next_record_index = II_index_list->next;
				for( k = 0; k < II_index_list->num; k++ )
				{
					GetLocalSearchList( &local_search_list, next_record_index->index );
					next_record_index = next_record_index->next;
				}
				lacb->head->num = (WORD)( lacb->head->num + II_index_list->num );
				II_index_list++;
			}
			I_index_list++; 
		}

		if( lacb->head->num == 0 )
			return lacb->head;

		if( ( record_head = SysLmalloc( sizeof(RECORDDATA) * lacb->head->num ) ) == NULL ) 
			return NULL;

		next_record_data = record_head;
		next_record_index = local_search_list;
		for( count = 0, i = 0; i < lacb->head->num; i++ )
		{
			next_record_head = record_head;
			for( j = 0; j < count; j++ )	//检查是否有多音字
			{
				if( next_record_head->index == next_record_index->index )
				{
					flag = 1;		//标志是多音字
					break;
				}
				next_record_head++;
			}
			if( flag != 1 )		
			{
				read_rv = GlobalReadRecord( lacb->gacb->PLInfo, next_record_index->index, &record );
				if( read_rv != DB_OK )
				{

⌨️ 快捷键说明

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