📄 carddb.c
字号:
/*************************************************************************
*
* 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 + -