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

📄 appdb.c

📁 一个操作系统源代码 用于嵌入式设备 在Vc++环境下仿真 成功移植到多款处理器上
💻 C
📖 第 1 页 / 共 2 页
字号:
BYTE* LocalReadRecord( DBLACB *lacb, DWORD id )
{
	BYTE	*record;

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

	if( lacb->gacb->symbol != DB_SYMBOL )
		return NULL;

	dbdbgprintf( "### Read Record ###" );
	record = lacb->gacb->funcs->localReadRecord( lacb, id);
	dbdbgprintf( "### Read Record OK ###" );
	return record;//返回读取的记录内容
}

/****************************************************************/
// 功能:修改指定数据库指定记录的内容
DWORD LocalModifyRecord( DBLACB *lacb, DWORD id, BYTE *data, WORD dataLen )
{
   //验证指定数据库连接的有效性
	if( lacb == NULL )
		return DB_ERROR;

	if( lacb->gacb->symbol != DB_SYMBOL )
		return DB_ERROR;

	//验证新记录数据的有效性
	if( data == NULL )//(数据不为空)
		return DB_ERROR;
	
	dbdbgprintf( "### Modify Record ###" );
	id = lacb->gacb->funcs->localModifyRecord( lacb, id, data, dataLen );//修改指定记录
	dbdbgprintf( "### Modify Record OK ###" );
	return id;
}

/****************************************************************/
// 功能:将指定记录添加到指定数据库中
DWORD LocalAddRecord( DBLACB *lacb, BYTE *data, WORD dataLen )
{
	DWORD   id;

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

	if( lacb->gacb->symbol != DB_SYMBOL )
		return DB_ERROR;

	//验证新记录数据的有效性
	if( data == NULL )//(数据不为空)
		return DB_ERROR;

	dbdbgprintf( "### Add Record ###" );
	id = lacb->gacb->funcs->localAddRecord( lacb, data, dataLen );//修改指定记录
	dbdbgprintf( "### Add Record OK ###" );
	return id;
}

/****************************************************************/
// 功能:删除指定数据库的指定记录
DWORD LocalDelRecord( DBLACB *lacb, DWORD id )
{
   //验证指定数据库连接的有效性
	if( lacb == NULL )
		return DB_ERROR;

	if( lacb->gacb->symbol != DB_SYMBOL )
		return DB_ERROR;

	dbdbgprintf( "### Delete Record ###" );
	id = lacb->gacb->funcs->localDelRecord( lacb, id );//修改指定记录
	dbdbgprintf( "### Delete Record OK ###" );
	return id;
}

/****************************************************************/
// 功能:在指定数据库中查找与指定字段匹配(完全匹配/部分匹配)的记录(精确查找)
LOCALSEARCHLIST* LocalFindRecord( DBLACB *lacb, BYTE field, BYTE *data, BYTE mode )
{
	LOCALSEARCHLIST		*recordindex;	

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

	if( lacb->gacb->symbol != DB_SYMBOL )
		return NULL;

	dbdbgprintf( "### Find Record ###" );
	recordindex = lacb->gacb->funcs->localFindRecord( lacb, field, data, mode );
	dbdbgprintf( "### Find Record OK ###" );
	return recordindex;
}

/****************************************************************/
// 功能:在指定数据库中查找与指定字段索引匹配(完全匹配/部分匹配)的记录(模糊查找)
//LOCALSEARCHLIST* LocalSearchRecord( DBLACB *lacb, BYTE field, BYTE *data, BYTE mode )
// 功能:对某目录下的目录和文件进行某字段的排序(此函数现只支持“记事本”数据库)
LOCALSEARCHLIST* LocalSortRecord( DBLACB *lacb, BYTE field, BYTE *data, BYTE reserved )
{
	LOCALSEARCHLIST		*recordindex;	

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

	if( lacb->gacb->symbol != DB_SYMBOL )
		return NULL;

	dbdbgprintf( "### Sort Record ###" );
	recordindex = lacb->gacb->funcs->localSortRecord( lacb, field, data, reserved );
	dbdbgprintf( "### Sort Record OK ###" );
	return recordindex;
}

/****************************************************************/
// 功能:对指定列表进行排序
LOCALSEARCHLIST* LocalSortList( DBLACB *lacb, LOCALSEARCHLIST *searchlist, BYTE field, BYTE reserved )
{
	LOCALSEARCHLIST		*recordindex;	

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

 	if( lacb->gacb->symbol != DB_SYMBOL )
		return NULL;

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

	dbdbgprintf( "### Sort Record List ###" );
	recordindex = lacb->gacb->funcs->localSortList( lacb, searchlist, field, reserved );
	dbdbgprintf( "### Sort Record List OK ###" );
	return recordindex;
}

/****************************************************************/
// 功能:立即保存DB到Flash中
DWORD SaveDB( DBLACB *lacb )
{
    //验证指定数据库连接的有效性
	if( lacb == NULL )
		return	DB_ERROR;

 	if( lacb->gacb->symbol != DB_SYMBOL )
		return DB_ERROR;

#ifndef	SIM_ON_PC
	fclosenow( lacb->gacb->PLInfo->fp );
	{
		BYTE id;
		id = (BYTE)( lacb->gacb - GAcb );
		lacb->gacb->PLInfo->fp = fopen( DBDescript[id].path, "rb+" );
	}
#endif
	return DB_OK;
}

/****************************************************************/
// 功能:释放旧的查找表
void DelOldSearchList( LOCALSEARCHLIST *searchlist )
{
	RECORDDATA	*next_record_data, *prev_record_data;

	dbdbgprintf( "### Delete Search Result ###" );
	if( searchlist != NULL )
	{
		next_record_data = searchlist->head;
		while( ( next_record_data != NULL ) && ( searchlist->num != 0 ) )
		{
			prev_record_data = next_record_data;
			next_record_data++;
			if( prev_record_data->data != NULL )
				SysLfree( prev_record_data->data );
			searchlist->num--;
		}
		SysLfree( searchlist->head );
		searchlist->head = NULL;
		searchlist->num = 0;
		SysLfree( searchlist );
	}
	dbdbgprintf( "### Delete Search Result OK ###" );
}

/****************************************************************/
//检测数据库文件是否正确
DWORD CheckBaseDate( DBGACB *gacb )
{
	DWORD			id = gacb->PLInfo->info.usedBlockHead, head = 0;
	WORD			i, count = 0;
	CHECKDBINDEX	*checkdbindex = NULL, *temp_checkdbindex, *pre_checkdbindex = NULL;
	FILE 			*fp = gacb->PLInfo->fp;
	
	if( gacb->symbol != DB_SYMBOL )
		return DB_FILE_ERROR;

	//检查头信息的正确性,头信息的地址应为4的整数倍
	if( id % 4 != 0 )	//不为4的整数倍,使数据库清空
	{
		head = 0;
		fwrite( &head, 4, 1, fp );// 在数据库文件中只有有效记录块的首地址(UBH)一项,其初始值为0
		return DB_FILE_ERROR;
	}

	gacb->PLInfo->info.usedBlockTail = 0;
	if( id != 0 )	// 判断记录是否为空
	{
		// 记录不为空
		DBRECORDHEAD	*head_info = NULL;
		BYTE	*record = NULL, *data;
#ifdef SIM_ON_PC
		WORD	*field;
#else
		WORD	field;
#endif

		WORD	record_size = 0;
		DWORD	rv = DB_OK;
		FIELDINDEXLIST	*field_index_list;
		DWORD	file_len;

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

			if( record == NULL )//空闲记录块
			{
				
				if( ( head_info = (DBRECORDHEAD *)SysLmalloc(sizeof(DBRECORDHEAD)) ) == NULL )
					return DB_ERROR;
				//检查空闲记录的size,空闲块长度要小于文件长度
//				fseek( fp, id+ADDRESS_BYTE_NUM, SEEK_SET );
//				fread( &head_info->size, SIZE_BYTE_NUM, 1, fp );
				if( record_size > file_len )	//空闲块长度大于文件长度
					return RewriteDBFile( count, gacb->PLInfo, checkdbindex );
				
				//检查空闲记录的symbol,空闲标志为FREE_BLOCK_FLAG
				fseek( fp, id+ADDRESS_BYTE_NUM+SIZE_BYTE_NUM, SEEK_SET );
				fread( &head_info->symbol, FLAG_BYTE_NUM, 1, fp );
				if( head_info->symbol != FREE_BLOCK_FLAG )	//空闲标志不为FREE_BLOCK_FLAG
					return RewriteDBFile( count, gacb->PLInfo, checkdbindex );
				
				//检查空闲记录的next,空闲记录的next要小于文件长度和为0
				fseek( fp, id+ADDRESS_BYTE_NUM+SIZE_BYTE_NUM+FLAG_BYTE_NUM, SEEK_SET );
				fread( &head_info->next, NEXT_BYTE_NUM, 1, fp );
				if( head_info->next > file_len || head_info->next != 0 )	//空闲记录的next大于文件长度,和不为0
//				if( head_info->next != 0 )		//空闲记录的next不为0
					return RewriteDBFile( count, gacb->PLInfo, checkdbindex );
								
				//检查空闲记录的prev,空闲记录的prev要小于文件长度
				fseek( fp, id+ADDRESS_BYTE_NUM+SIZE_BYTE_NUM+FLAG_BYTE_NUM+NEXT_BYTE_NUM, SEEK_SET );
				fread( &head_info->prev, PREV_BYTE_NUM, 1, fp );
//				if( gacb->PLInfo->info.usedBlockTail != head_info->prev )	//前一个记录与空闲记录记录不相符
				if( ( gacb->PLInfo->info.usedBlockTail != head_info->prev ) || ( ( head_info->prev) % 4 != 0 ) )	//前一个记录与当前记录不相符
				{
					SysLfree(head_info);
					return RewriteDBFile( count, gacb->PLInfo, checkdbindex );
				}else{
					SysLfree(head_info);
					goto endrv;
				}
			}else{	//有效记录块
				if( count == 0 )
				{
					gacb->PLInfo->info.usedBlockTail = id;
				}
				head_info = (DBRECORDHEAD *)record;
				
				//检查当前记录的size,记录长度要小于文件长度
				if( head_info->size > file_len )//记录长度大于文件长度
					return RewriteDBFile( count, gacb->PLInfo, checkdbindex );
				
				//检查记录的symbol,空闲标志为USED_BLOCK_FLAG
				if( head_info->symbol != USED_BLOCK_FLAG )	//空闲标志不为USED_BLOCK_FLAG
					return RewriteDBFile( count, gacb->PLInfo, checkdbindex );
				
				//检查当前记录的next,记录的next要小于文件长度和不为0
				if( ( head_info->next > file_len ) || ( head_info->next )% 4 != 0 )	//记录的next大于文件长度,和不为0
//				if( ( head_info->next == 0 ) && ( gacb->PLInfo->info.freeBlockNum != 0 ) )
					return RewriteDBFile( count, gacb->PLInfo, checkdbindex );
								
				//检查当前记录的prev,记录的prev要小于文件长度, 前一个记录与当前记录不相符
				if( ( head_info->prev > file_len ) || ( gacb->PLInfo->info.usedBlockTail != head_info->prev ) || ( ( head_info->prev) % 4 != 0 ))	//前一个记录与当前记录不相符
//				if( ( gacb->PLInfo->info.usedBlockTail != head_info->prev ) || ( ( head_info->prev) % 4 != 0 ) )	//前一个记录与当前记录不相符
					return RewriteDBFile( count, gacb->PLInfo, checkdbindex );

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

				//检查记录中字段值的偏移,偏移必须小于( record_size - (SIZE_BYTE_NUM+FLAG_BYTE_NUM+NEXT_BYTE_NUM+PREV_BYTE_NUM) ))
				field_index_list = gacb->FList;
//				for( i = 0; i < gacb->IFNum; i++ )
				for( i = 0; i < gacb->fieldNum; 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], prev_field_value; 
#else
						WORD	next_field_value = field, prev_field_value, temp; 
#endif
						while( next_field_value != 0 )
						{
							prev_field_value = next_field_value;
							// 根据字段类型取出字段值
							switch( field_index_list->type )
							{
								case MULTI_VALUE_FIELD:		// 多值字段,带字段值索引
#ifdef SIM_ON_PC
									next_field_value = *(WORD *)( data + next_field_value );
#else
									temp = next_field_value;
									Bytes2Word( &next_field_value, data + next_field_value );
#endif
									break;
								case SINGLE_VALUE_FIELD:	// 单值字段,不带字段值索引
									next_field_value = 0;
									break;
							}
							if( ( next_field_value > ( record_size - (SIZE_BYTE_NUM+FLAG_BYTE_NUM+NEXT_BYTE_NUM+PREV_BYTE_NUM) ) )
								|| ( prev_field_value > next_field_value ) )
							{
								return RewriteDBFile( count, gacb->PLInfo, checkdbindex );
							}
						}
					}
					field_index_list++;
				}
				if( count != 0 )
				{
					gacb->PLInfo->info.usedBlockTail = id;
				}
				id = head_info->next;
			}
			//把记录暂存入缓冲区
			if( ( temp_checkdbindex = (CHECKDBINDEX *)SysLmalloc( sizeof(CHECKDBINDEX) ) ) == NULL )
				return DB_ERROR;
			temp_checkdbindex->record = record;
			temp_checkdbindex->next = NULL;
			if( count == 0 )
			{
				checkdbindex = temp_checkdbindex;
				pre_checkdbindex = checkdbindex;
			}else{
				pre_checkdbindex->next = temp_checkdbindex;
				pre_checkdbindex = temp_checkdbindex;
			}
			count++;
		}while( id != 0 );
	}

endrv:
	temp_checkdbindex = checkdbindex;
	while( temp_checkdbindex != NULL )
	{
		pre_checkdbindex = temp_checkdbindex;
		temp_checkdbindex = pre_checkdbindex->next;
		SysLfree( pre_checkdbindex );
	}
	SysLfree( gacb->PLInfo );
	return DB_OK;
}

/****************************************************************/
//数据库出错,更新数据库数据
DWORD RewriteDBFile( WORD count, DBPHYLAYERINFO *info, CHECKDBINDEX *checkdbindex )
{
	CHECKDBINDEX	*next_checkdbindex, *pre_checkdbindex;
	WORD			i;
	DWORD			head, id = 0;

	if( count == 0 )
	{
		head = 0;
		fwrite( &head, 4, 1, info->fp );// 在数据库文件中只有有效记录块的首地址(UBH)一项,其初始值为0
	}else{
		next_checkdbindex = checkdbindex;
		for( i = 0; i < count; i++ )
		{
			id = GlobalInsertRecord( info, id, next_checkdbindex->record );//添加新记录到数据库
			if( ( id == DB_ERROR ) || ( id == DB_FREE_RECORD ) )
				return DB_ERROR;
			pre_checkdbindex = next_checkdbindex;
			next_checkdbindex = next_checkdbindex->next;
			SysLfree( pre_checkdbindex );
		}
	}
	SysLfree( info );

	return DB_FILE_ERROR;
}

⌨️ 快捷键说明

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