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