📄 common.c
字号:
#include <database\common.h>
/**********************************************************************/
DBLACB* LinkDB( DBGACB *gacb )
{
DBLACB *lacb;
if( ( lacb = (DBLACB *)SysLmalloc( sizeof(DBLACB) ) ) == NULL )
return NULL;
lacb->gacb = gacb;
lacb->head = NULL;
return lacb;
}
/**********************************************************************/
BYTE* ReadDBRecord( DBLACB *lacb, DWORD id )
{
BYTE *record;
DWORD rv = DB_OK;
rv = GlobalReadRecord( lacb->gacb->PLInfo, id, &record ); //调用GlobalReadRecord读取指定记录的内容
if( rv != DB_OK )
record = NULL;
return record; //返回读取的记录内容
}
/**********************************************************************/
void DelRecordIndexTbl( DBLACB *lacb, DWORD id )
{
BYTE field_I_index, field_II_index; //一二级索引
DWORD *II_index_list; //二级索引表
RECORDINDEX *record_index, *next_record_index, *prev_record_index; //暂存记录字段表中的记录的地址
FIELDVALUEINDEX *field_value_index, *next_field_index; //暂存字段值索引结构的地址
RECORDINDEX *cur_index, *next_index, *prev_index; //暂存字段索引表中记录的地址
FIELDINDEX *II_index;
WORD i;
field_I_index = (BYTE)( id & 0x1f ); //取id的低5位为一级索引
field_II_index = (BYTE)( ( id >> 5 ) & 0x1f ); //取id的从低起的6~10位为二级索引
II_index_list = (DWORD *)(lacb->gacb->RFList[field_I_index]); //获取二级索引的的值
//根据记录字段值索引将要修改记录的记录索引从字段索引表中删除及该记录下的所有字段值索引
next_record_index = record_index = prev_record_index = (RECORDINDEX *)II_index_list[field_II_index];
i = 0; //计算记录字段表的二级索引上记录的个数
while( next_record_index != NULL )
{
prev_record_index = record_index; //保存要修改记录的前一条记录
record_index = next_record_index; //保存要修改记录
next_record_index = next_record_index->next; //保存要修改记录的后一条记录
if( record_index->index == id ) //找到该记录
{
next_field_index = record_index->head;
if( i == 0 ) //记录字段表的二级索引只有一个记录
{
II_index_list[field_II_index] = 0;
}else{//记录字段表的二级索引不止有一个记录
prev_record_index->next = record_index->next; //链接要修改的记录之后的链表
}
SysLfree( record_index ); //释放记录字段表中的记录索引结构
while( next_field_index != NULL )
{
cur_index = next_field_index->index;
next_index = cur_index->next;
prev_index = cur_index->prev;
SysLfree( cur_index ); //释放字段索引表中的记录索引结构
if( next_index != NULL ) //更新下一个记录
{
next_index->prev = prev_index;
}
if( prev_index->prev == NULL ) //prev_index为二级索引
{
II_index = (FIELDINDEX *)prev_index; //强制转换为二级索引的结构(重新解析结构体)
II_index->next = next_index; //更新前一个记录
}else{
prev_index->next = next_index; //更新前一个记录
//寻找二级索引
while( prev_index != NULL )
{
next_index = prev_index;
prev_index = next_index->prev;
}
II_index = (FIELDINDEX *)next_index;//强制转换为二级索引的结构(重新解析结构体)
}
II_index->num--; //更新二级索引的索引数
field_value_index = next_field_index;
next_field_index = field_value_index->next;
SysLfree( field_value_index ); //释放字段值结构表
}
break;
}
i++;
}
}
/**********************************************************************/
//填充修改后的数据
DWORD AddModifiedRecordData( DBPHYLAYERINFO *info, DWORD id, BYTE *data, WORD dataLen, BYTE *record )
{
BYTE *record_data;
if( ( record_data = (BYTE *)SysLmalloc( dataLen + SIZE_BYTE_NUM + FLAG_BYTE_NUM + NEXT_BYTE_NUM + PREV_BYTE_NUM ) ) == NULL )
return DB_ERROR;
dataLen += ( SIZE_BYTE_NUM + FLAG_BYTE_NUM + NEXT_BYTE_NUM + PREV_BYTE_NUM );
memcpy( record_data, &dataLen, SIZE_BYTE_NUM );
record_data += SIZE_BYTE_NUM;
record += SIZE_BYTE_NUM;
memcpy( record_data, record, ( FLAG_BYTE_NUM + NEXT_BYTE_NUM + PREV_BYTE_NUM ) );
record_data += ( FLAG_BYTE_NUM + NEXT_BYTE_NUM + PREV_BYTE_NUM );
record -= SIZE_BYTE_NUM;
memcpy( record_data, data, ( dataLen-( SIZE_BYTE_NUM + FLAG_BYTE_NUM + NEXT_BYTE_NUM + PREV_BYTE_NUM )) );
record_data += ( dataLen-( SIZE_BYTE_NUM + FLAG_BYTE_NUM + NEXT_BYTE_NUM + PREV_BYTE_NUM ) );
record_data -= dataLen;
id = GlobalModifyRecord( info, id, record_data ); //保存修改后的记录
SysLfree( record );
SysLfree( record_data );
if( ( id == DB_ERROR ) || ( id == DB_FREE_RECORD ) )
return DB_ERROR;
return id;
}
/**********************************************************************/
//填充修改后的数据
DWORD AddNewRecordData( DBPHYLAYERINFO *info, BYTE *data, WORD dataLen )
{
BYTE *record_data;
WORD used_block_flag = USED_BLOCK_FLAG;
DWORD id = 0;
//填充新添加的数据
if( ( record_data = (BYTE *)SysLmalloc( dataLen + SIZE_BYTE_NUM + FLAG_BYTE_NUM + NEXT_BYTE_NUM + PREV_BYTE_NUM) ) == NULL )
return DB_ERROR;
dataLen += ( SIZE_BYTE_NUM + FLAG_BYTE_NUM + NEXT_BYTE_NUM + PREV_BYTE_NUM );
memcpy( record_data, &dataLen, SIZE_BYTE_NUM );
record_data += SIZE_BYTE_NUM;
memcpy( record_data, &used_block_flag, SIZE_BYTE_NUM );
record_data += FLAG_BYTE_NUM;
record_data += ( NEXT_BYTE_NUM + PREV_BYTE_NUM );
memcpy( record_data, data, (dataLen-( SIZE_BYTE_NUM + FLAG_BYTE_NUM + NEXT_BYTE_NUM + PREV_BYTE_NUM )) );
record_data += (dataLen-( SIZE_BYTE_NUM + FLAG_BYTE_NUM + NEXT_BYTE_NUM + PREV_BYTE_NUM ));
record_data -= dataLen;
id = GlobalInsertRecord( info, id, record_data );//添加新记录到数据库
SysLfree( record_data );
if( ( id == DB_ERROR ) || ( id == DB_FREE_RECORD ) )
return DB_ERROR;
return id;
}
/**********************************************************************/
//添加记录在二级索引的记录表中(记录表无序,先来先加)
RECORDINDEX *Add2RecordIndexTbl( FIELDINDEX *II_index_list, DWORD id )
{
RECORDINDEX *new_record_head, *next_record_head, *next_head, *prev_head;
//申请新纪录的结构
if( ( new_record_head = (RECORDINDEX *)SysLmalloc( sizeof(RECORDINDEX) ) ) == NULL )
return NULL;
next_record_head = II_index_list->next;
if( next_record_head == NULL ) //记录表为空
{
II_index_list->next = new_record_head;
//更新当前记录
new_record_head->next = NULL;
new_record_head->prev = (RECORDINDEX *)II_index_list;
new_record_head->index = id;
}else{ //记录表不为空
//插在tem_id的前面
next_head = next_record_head;
prev_head = next_record_head->prev;
//更新后一个记录
next_head->prev = new_record_head;
//更新当前记录
new_record_head->next = next_head;
new_record_head->prev = prev_head;
new_record_head->index = id;
//更新前一个记录
II_index_list->next = new_record_head;
}
II_index_list->num++;//更新二级索引的索引数
return ( new_record_head );
}
/**********************************************************************/
// 将字段索引加入到记录字段表
DWORD Add2RecordIndex( RECORDINDEX **list[], DWORD id, RECORDINDEX *p )
{
BYTE field_I_index, field_II_index; //一二级索引
DWORD *II_index_list; //二级索引表
RECORDINDEX *cur_record, *next_record, *prev_record, *temp_II_head;
FIELDVALUEINDEX *new_field_value, *field_index, *next_field_index;
BYTE i;
field_I_index = (BYTE)( id & 0x1f ); //取id的低5位为一级索引
field_II_index = (BYTE)( ( id >> 5 ) & 0x1f ); //取id的从低起的6~10位为二级索引
if( list[ field_I_index ] == NULL ) //二级索引表为空,新建二级索引表
{
if( ( II_index_list = (DWORD *)SysLmalloc( sizeof(DWORD) * RECORD_FIELD_LIST_LEN ) ) == NULL )
return DB_ERROR;
list[ field_I_index ] = (RECORDINDEX **)II_index_list;
for( i = 0; i < RECORD_FIELD_LIST_LEN; i++)
II_index_list[i] = 0;
}
II_index_list = (DWORD *)list[ field_I_index ];
temp_II_head = next_record = (RECORDINDEX *)(II_index_list[field_II_index]); //获取记录字段的表头
while( next_record != NULL ) //添加新字段
{
if( next_record->index == id ) //同记录,则把字段加在字段表尾
{
field_index = next_record->head;
next_field_index = field_index->next;
while( next_field_index != NULL )
{
field_index = next_field_index;
next_field_index = field_index->next;
}
if( ( new_field_value = (FIELDVALUEINDEX *)SysLmalloc( sizeof(FIELDVALUEINDEX) ) ) == NULL ) //申请字段值空间
return DB_ERROR;
field_index->next = new_field_value; //把新的字段值结构链在原字段结构上
//更新字段值结构
new_field_value->index = p;
new_field_value->next = NULL;
return DB_OK;
}
prev_record = next_record;
next_record = next_record->next;
}
//新建记录索引结构
if( ( cur_record = (RECORDINDEX *)SysLmalloc( sizeof(RECORDINDEX) ) ) == NULL )
return DB_ERROR;
if( ( new_field_value = (FIELDVALUEINDEX *)SysLmalloc( sizeof(FIELDVALUEINDEX) ) ) == NULL ) //申请字段值空间
{
SysLfree( cur_record );
return DB_ERROR;
}
if( temp_II_head == NULL ) //把新纪录链在二级索引表上
{
II_index_list[field_II_index] = (DWORD)cur_record;
}else{ //把新纪录链在记录字段表尾
prev_record->next = cur_record;
}
//更新字段值结构
new_field_value->index = p;
new_field_value->next = NULL;
//更新记录索引结构
cur_record->next = NULL;
cur_record->prev = NULL;
cur_record->head = new_field_value;
cur_record->index = id;
return DB_OK;
}
/**********************************************************************/
//获取姓名字段值的一二级索引
void GetNameFieldIandIIIndex( BYTE *field_value, WORD *field_I_index, WORD *field_II_index , BYTE *PY_num)
{
BYTE i, j;
WORD ASCII_char; //存放首字的ASCII码
BYTE section_id_I; //汉字一级索引表的偏移
WORD section_id_II; //汉字二级索引表的偏移
WORD PY_offset = 0; //汉字辅助索引表的偏移
BYTE *temp;
temp = field_value;
if( ( ( *temp ) & 0x80 ) == 0x80 ) //是汉字
{
ASCII_char = (WORD)( ( *temp << 8 ) | ( *(temp+1) ) );
section_id_I = (BYTE)( GetSectionID( ASCII_char ) ); // 根据汉字的GB编码获取分区号
section_id_II = (WORD)( Gb2PyTbl_I[section_id_I] << 1 ); // 定位到二级索引表的具体区那
for( i = 0; i < NUM_PRE_SECTION; i++ )
{
if( ASCII_char == Gb2PyTbl_II[ section_id_II ] )
{
*field_II_index = Gb2PyTbl_II[ section_id_II + 1 ];
*PY_num = (BYTE)( ( (*field_II_index) >> 14 ) & 0x03 ); //确定汉字是否是多音字
if( *PY_num != 0 ) //多音字
{
PY_offset = (WORD)( *field_II_index & 0x3fff ); //在辅助索引表中的偏移
for( j = 0; j <= (*PY_num); j++ )
{
field_II_index[j] = (WORD)( Gb2PyTbl_A[PY_offset] & 0x007f );
field_I_index[j] = (WORD)( ( Gb2PyTbl_A[PY_offset] >> 7 ) & 0x007f );
PY_offset++;
}
}
else if( *PY_num == 0 )
{
if( *field_II_index == 0x3fff ) //无此汉字
{
*field_I_index = 123;
*field_II_index = 53;
}else{//单音字
*field_I_index = (WORD)( ( (*field_II_index) >> 7 ) & 0x007f );
*field_II_index = (WORD)( (*field_II_index) & 0x007f );
}
}
break;
}
section_id_II = (WORD)( section_id_II + 2 );
}
}else{ //是字符
ASCII_char = (WORD)(*temp);
//区分大小写
if( ( ASCII_char > 'A' ) && ( ASCII_char < 'Z' ) )
ASCII_char = (WORD)( ASCII_char + 32 );
//其他字符
if( ( ASCII_char < 'a' ) || ( ASCII_char > 'z' ) )
ASCII_char = 123;
*field_I_index = ASCII_char;
*field_II_index = 53;
}
return;
}
/**********************************************************************/
//比较字符
CHAR CompareChar( BYTE *field_value, BYTE *tmp_field_value )
{
//新记录
WORD field_I_index[PY_MAX_NUM], field_II_index[PY_MAX_NUM];
//已排列的记录
WORD temp_field_I_index[PY_MAX_NUM], temp_field_II_index[PY_MAX_NUM]; //字段一二级索引值
BYTE PY_num;
CHAR rv = 0;
GetNameFieldIandIIIndex( tmp_field_value, temp_field_I_index, temp_field_II_index, &PY_num); //将关键字转化为索引
GetNameFieldIandIIIndex( field_value, field_I_index, field_II_index, &PY_num); //将关键字转化为索引
if( *temp_field_I_index < *field_I_index )
{
rv = 1; //新纪录插入当前位置的后面
}
else if( *temp_field_I_index > *field_I_index )
{
rv = -1;
}
else if( *temp_field_I_index == *field_I_index )
{
if( *temp_field_II_index < *field_II_index )
{
rv = 1;
}
else if( *temp_field_II_index > *field_II_index )
{
rv = -1;
}
else if( *temp_field_II_index == *field_II_index )
{
rv = strcmp( field_value, tmp_field_value ); //判断名称的大小
}
}
return rv;
}
/**********************************************************************/
//形成新的局部查找表
DWORD GetLocalSearchList( RECORDINDEX **local_search_list, DWORD id )
{
RECORDINDEX *tmp_local_list;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -