CEDataBase.h文件
#pragma once
//数据库类型的枚举值
//可以对此枚举进行拓展,但是在响应使用的函数里都要进行拓展
enum
{
PRO_STRING = 0x00000001, //字符串类型 TCHAR
PRO_TIME, //日期型 systime
PRO_NUMBER //整型 int
};
//
//说明 Begin:每次使用该数据库类,只需要修改此处的数据结构
//***定义传递记录的结构体***
typedef struct
{
TCHAR LinkmanName[20];
TCHAR MobilePhone1[21];
TCHAR MobilePhone2[21];
TCHAR OfficePhone[21];
TCHAR HomePhone[21];
TCHAR Company[40];
TCHAR QQ[15];
//char name[20];
}DATA_RECORD,*DATA_pRECORD;
//***数据库属性的总个数***
#define PROPERTY_NUM 7
//属性类型数组
extern DWORD PROPERTY_TYPE_ID[PROPERTY_NUM];
//自定义属性类型数组
extern DWORD PROPERTY_TYPE[PROPERTY_NUM];
//数据对象在结构体中的位置
extern int PROPERTY_POSITION[PROPERTY_NUM];
//定义数据库文件名
#define DBFILENAME L"\\My Documents\\contact.vol"
//定义数据库名
#define DBTABLENAME L"\\contact"
//定义联系人姓名字段标识,联系人姓名在数据库中将是唯一型字段
#define PID_NAME MAKELONG(CEVT_LPWSTR,0)
//定义联系人手机号码1字段标识
#define PID_NUMBER1 MAKELONG(CEVT_LPWSTR,1)
//定义联系人手机号码2字段标识
#define PID_NUMBER2 MAKELONG(CEVT_LPWSTR,2)
//定义联系人办公室电话号码标识
#define PID_NUMBER3 MAKELONG(CEVT_LPWSTR,3)
//定义联系人家庭电话号码标识
#define PID_NUMBER4 MAKELONG(CEVT_LPWSTR,4)
//定义联系人单位名称标识
#define PID_COMPANYNAME MAKELONG(CEVT_LPWSTR,5)
//定义联系人QQ标识
#define PID_QQ MAKELONG(CEVT_LPWSTR,6)
//说明 End:每次使用该数据库类,只需要修改此处的数据结构
//
class CEDataBase
{
//属性
private:
CEGUID m_ceGuid; //存储数据库文件卷标识(GUID)PCEGUID m_pCeGuid;
CEOID m_ceOid; //DWORD型 存储数据库对象标识和记录对象标识,惟一标识数据库的ID,CeCreateDatabaseEx()返回
HANDLE m_hDB; //存储数据库句柄,CeOpenDatabaseEx()返回
HANDLE m_hSession; //会话句柄
public:
CString m_DataBase; //数据库路径及卷文件名称
CString m_TableName; //操作的数据表名称
//操作
public:
CEDataBase(void);
~CEDataBase(void);
public:
BOOL Open(void); //打开数据库
BOOL Create(DWORD dwIndex); //创建数据库
BOOL Close(void); //关闭数据库
BOOL UnmountDBVol(void); //卸载数据库卷,仅在打开数据库完全失败时使用
DWORD Seek(DWORD dwID); //移动记录指针
int GetRecordCount(); //返回表内的记录总数
BOOL GetRecord(DWORD dwID,DATA_RECORD *pRecord); //返回指定ID的记录结构体指针
BOOL Add(DATA_RECORD *pRecord); //添加一条记录
BOOL Delete(DWORD dwIndex); //删除某条记录
BOOL Modify(DWORD dwID,DATA_RECORD * pRecord); //修改某条记录
};
CEDataBase.cpp文件
#include "StdAfx.h"
#include "CEDataBase.h"
//
//说明 Begin:每次使用该数据库类,只需要修改此处的数据结构
//***属性类型数组***
//按照结构体个数依次排列
//MAKELONG第一个参数为其数据库中的数据类型
// 第二个参数为其ID,递增即可
DWORD PROPERTY_TYPE_ID[PROPERTY_NUM] = {
MAKELONG(CEVT_LPWSTR,1),
MAKELONG(CEVT_LPWSTR,2),
MAKELONG(CEVT_LPWSTR,3),
MAKELONG(CEVT_LPWSTR,4),
MAKELONG(CEVT_LPWSTR,5),
MAKELONG(CEVT_LPWSTR,6),
MAKELONG(CEVT_LPWSTR,7)
};
//***自定义属性类型数组***
//按照结构体个数依次排列
DWORD PROPERTY_TYPE[PROPERTY_NUM] = {
PRO_STRING,
PRO_STRING,
PRO_STRING,
PRO_STRING,
PRO_STRING,
PRO_STRING,
PRO_STRING
};
//***数据对象在结构体中的位置***
int PROPERTY_POSITION[PROPERTY_NUM] = {
0,
20,
20+20
};
//说明 End:每次使用该数据库类,只需要修改此处的数据结构
//
//--------------------------------------------------------------------
//【函数介绍】: 构造和析构函数
//
//【入口参数】: (无)
//
//【出口参数】: (无)
//【返回 值】:
//---------------------------------------------------------------------
CEDataBase::CEDataBase(void)
{
//初始化数据库句柄
m_hDB = 0;
//将数据库对象标识设置0
m_ceOid = 0;
m_DataBase=_T("\\My Documents\\contact.vol"); //数据库路径及卷文件名称
m_TableName=_T("\\contact"); //操作的数据表名称
}
CEDataBase::~CEDataBase(void)
{
}
//--------------------------------------------------------------------
//【函数介绍】: UINT CEDataBase::Open(void)
// 打开数据库,如果返回 ERROR_FILE_NOT_FOUND 表明数据库不存在,需要Create函数
// 打开成功返回 0
//【入口参数】: (无)
//
//【出口参数】: (无)
//【返回 值】: 0 为成功,否则失败
//---------------------------------------------------------------------
BOOL CEDataBase::Open(void)
{
//挂载数据库卷,如果存在则打开,不存在,就新建一个
if (!CeMountDBVol(&m_ceGuid,m_DataBase.GetBuffer(),OPEN_ALWAYS))
{
TRACE(_T("CEDataBase001:打开或新建数据卷失败\n"));
return FALSE;
}
//接着打开数据库
m_hDB = CeOpenDatabaseEx(&m_ceGuid,&m_ceOid,m_TableName.GetBuffer(),NULL,CEDB_AUTOINCREMENT,NULL);
if (m_hDB == INVALID_HANDLE_VALUE)
{
//如果数据库不存在,就新建之
Create(PID_NAME);
}
return TRUE;
}
//--------------------------------------------------------------------
//【函数介绍】: BOOL CEDataBase::Create(DWORD dwIndex)
// 创建数据库,如果打开没有成功,则判断返回值是否为,是 ERROR_FILE_NOT_FOUND 则创建数据库
//【入口参数】: dwIndex 为Define的MAKELONG宏定义的某个属性的DWORD值
//
//【出口参数】: (无)
//【返回 值】: TRUE为创建成功,FALSE为创建失败
//---------------------------------------------------------------------
BOOL CEDataBase::Create(DWORD dwIndex)
{
CEDBASEINFO ceDbInfo;
ceDbInfo.dwFlags = CEDB_VALIDNAME | CEDB_VALIDTYPE | CEDB_VALIDSORTSPEC;
wcscpy(ceDbInfo.szDbaseName , m_TableName.GetBuffer());
ceDbInfo.dwDbaseType = 0;
ceDbInfo.wNumSortOrder = 1; //排序索引字段数目,此处暂定为1个索引
ceDbInfo.rgSortSpecs[0].propid = dwIndex;
ceDbInfo.rgSortSpecs[0].dwFlags = CEDB_SORT_CASEINSENSITIVE; //升序,且大小写无关
//此处只要参数允许,最多可以设置4个索引,此处暂定为1个索引
//ceDbInfo.rgSortSpecs[1].propid = PID_TEL;
//ceDbInfo.rgSortSpecs[1].dwFlags = CEDB_SORT_CASEINSENSITIVE; //升序,且大小写无关
m_ceOid = CeCreateDatabaseEx(&m_ceGuid,&ceDbInfo);
if (m_ceOid == 0)
{
TRACE(_T("CEDataBase005:创建数据库失败\n"));
//此处得卸载数据库卷
if (!CeUnmountDBVol(&m_ceGuid))
{
TRACE(_T("CEDataBase006:卸载数据库文件卷失败\n"));
return FALSE;
}
return FALSE;
}
//创建数据库后,应紧接着打开数据库
m_hDB = CeOpenDatabaseEx(&m_ceGuid,&m_ceOid,m_TableName.GetBuffer(),NULL,CEDB_AUTOINCREMENT,NULL);
if (m_hDB == INVALID_HANDLE_VALUE)
{
TRACE(_T("CEDataBase007:打开数据库失败\n"));
//此处得卸载数据库卷
if (!CeUnmountDBVol(&m_ceGuid))
{
TRACE(_T("CEDataBase008:卸载数据库文件卷失败\n"));
return FALSE;
}
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------
//【函数介绍】: BOOL CEDataBase::Close(void)
// 关闭数据库
//【入口参数】: (无)
//
//【出口参数】: (无)
//【返回 值】: TRUE为创建成功,FALSE为创建失败
//---------------------------------------------------------------------
BOOL CEDataBase::Close(void)
{
//1、关闭数据库
if (!CloseHandle(m_hDB))
{
TRACE(_T("CEDataBase002:关闭数据库失败\n"));
return FALSE;
}
//2、将数据库卷的数据缓冲到永久存储介质上
if (!CeFlushDBVol(&m_ceGuid))
{
TRACE(_T("CEDataBase003:缓冲介质失败\n"));
return FALSE;
}
//3、卸载数据库卷
if (!CeUnmountDBVol(&m_ceGuid))
{
TRACE(_T("CEDataBase004:卸载数据库文件卷失败\n"));
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------
//【函数介绍】: BOOL CEDataBase::UnmountDBVol(void)
// 仅供数据库文件存在,并且打开错误的时候卸载使用
//【入口参数】: (无)
//
//【出口参数】: (无)
//【返回 值】: TRUE为卸载成功,FALSE为卸载失败
//---------------------------------------------------------------------
BOOL CEDataBase::UnmountDBVol(void)
{
//此处得卸载数据库卷
if (!CeUnmountDBVol(&m_ceGuid))
{
TRACE(_T("CEDataBase009:卸载数据库文件卷失败\n"));
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------
//【函数介绍】: DWORD CEDataBase::Seek(DWORD dwID)
// 从开始位置移动dwID个数据指针
//【入口参数】: (无)
//
//【出口参数】: (无)
//【返回 值】: 成功返回不为零数值
//---------------------------------------------------------------------
DWORD CEDataBase::Seek(DWORD dwID)
{
CEOID ceOid;
DWORD dwIndex;
ceOid = CeSeekDatabase(m_hDB,CEDB_SEEK_BEGINNING,dwID,&dwIndex);
ASSERT(ceOid !=0);
return ceOid;
}
//--------------------------------------------------------------------
//【函数介绍】: BOOL GetRecord(DWORD dwID,DATA_RECORD * pRecord);
// 返回指定ID的记录结构体指针
//
//【入口参数】: DWORD dwID 指定返回内容的ID
//
//【出口参数】: DATA_RECORD * pRecord 返回数据的结构体
//【返回 值】: 返回TRUE为成功,返回FALSE为失败
//---------------------------------------------------------------------
BOOL CEDataBase::GetRecord(DWORD dwID,DATA_RECORD *pRecord)
{
CEOID ceOid;
WORD wProps = 0; //查询数据库后返回的指定表的属性个数
DWORD dwRecSize = 0;
DWORD dwInSize = 0;
PBYTE pBuff;
PCEPROPVAL pRecordVal;
char * pRecNew = (char *)pRecord;
//移动记录指针
ceOid = CeSeekDatabase(m_hDB,CEDB_SEEK_BEGINNING,dwID,&dwRecSize);
ASSERT(ceOid !=0);
pBuff = 0;
ceOid = CeReadRecordProps(m_hDB,CEDB_ALLOWREALLOC,&wProps,NULL,&(LPBYTE)pBuff,&dwInSize);
ASSERT(ceOid != 0);
pRecordVal = (PCEPROPVAL)pBuff;
for (int i=0; i<wProps; i++)
{
//查找当前属性与之匹配的MAKELONG值在PROPERTY_TYPE_ID数组中的ID
int iPos = 9999; //默认9999为错误值,即没有找到匹配值
for(int t=0; t<wProps; t++)
{
iPos = 9999;
if(PROPERTY_TYPE_ID[t] == pRecordVal->propid)
{
iPos = t;
break;
}
}
if((iPos == 9999) || (iPos > PROPERTY_NUM) || (iPos < 0))
{
TRACE(_T("CEDataBase010:没有找到匹配的属性\n"));
//return FALSE;
}
else
{
//找到了匹配的属性,并赋值给结构体
switch(PROPERTY_TYPE[iPos])
{
case PRO_STRING:
{
wcscpy((LPWSTR)(pRecNew+PROPERTY_POSITION[i]),pRecordVal->val.lpwstr);
break;
}
case PRO_TIME:
{
memcpy((void *)(pRecNew+PROPERTY_POSITION[i]),(void *)&(pRecordVal->val.filetime),sizeof(FILETIME));
//TRACE1("Sizeof DATA_RECORD = %d \n",sizeof(DATA_RECORD));
//TRACE1("Sizeof DATA_RECORD = %d \n",sizeof(pRecord->szName));
//TRACE1("Sizeof FILETIME = %d \n",sizeof(pRecord->ftBirthday));
//TRACE1("Sizeof FILETIME = %d \n",sizeof(pRecord->szTel));
break;
}
//升级备注:其他数据类型的case在此添加
}
}
pRecordVal++;
}
LocalFree(pBuff);
return TRUE;
}
//--------------------------------------------------------------------
//【函数介绍】: int GetRecordCount();
// 返回表内记录的个数
//【入口参数】: (无)
//
//【出口参数】: (无)
//【返回 值】: 返回表内记录的个数
//---------------------------------------------------------------------
int CEDataBase::GetRecordCount()
{
int iCount;
CEOIDINFO oidinfo;
if (!CeOidGetInfoEx(&m_ceGuid,m_ceOid,&oidinfo))
{
TRACE(_T("CEDataBase011:获取信息失败\n"));
return -1;
}
iCount = oidinfo.infDatabase.wNumRecords;
return iCount;
}
//--------------------------------------------------------------------
//【函数介绍】: BOOL CEDataBase::Delete(DWORD dwIndex)
// 删除指定ID的记录
//【入口参数】: (无)
//
//【出口参数】: (无)
//【返回 值】: 返回TRUE为成功,返回FALSE为失败
//---------------------------------------------------------------------
BOOL CEDataBase::Delete(DWORD dwIndex)
{
if(dwIndex < 0)
return FALSE;
DWORD dwRet;
CEOID ceOid;
ceOid = CeSeekDatabase(m_hDB,CEDB_SEEK_BEGINNING,dwIndex,&dwRet);
ASSERT(ceOid !=0 );
if (!CeDeleteRecord(m_hDB,ceOid))
{
TRACE(_T("CEDataBase012:数据库删除失败\n"));
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------
//【函数介绍】: BOOL CEDataBase::Add(DATA_RECORD * pRecord)
// 添加单个联系人
//【入口参数】: (无)
//
//【出口参数】: (无)
//【返回 值】: 返回TRUE为成功,返回FALSE为失败
//---------------------------------------------------------------------
BOOL CEDataBase::Add(DATA_RECORD *pRecord)
{
CEOID ceOid = 0;
CEPROPVAL *pRecordVal = new CEPROPVAL[PROPERTY_NUM];
//TRACE1("Sizeof CEPROPVAL = %d \n",sizeof(CEPROPVAL));
char * pRecNew = (char *)pRecord;
for(int i=0; i<PROPERTY_NUM; i++)
{
memset(pRecordVal,0,sizeof(CEPROPVAL));
pRecordVal->propid = PROPERTY_TYPE_ID[i];
switch(PROPERTY_TYPE[i])
{
case PRO_STRING:
{
pRecordVal->val.lpwstr = (wchar_t *)(pRecNew+PROPERTY_POSITION[i]);
break;
}
case PRO_TIME:
{
memcpy((void *)&(pRecordVal->val.filetime),(void *)(pRecNew+PROPERTY_POSITION[i]),sizeof(FILETIME));
break;
}
//升级备注:其他数据类型的case在此添加
}
pRecordVal++;
}
pRecordVal = pRecordVal - PROPERTY_NUM; //(PROPERTY_NUM - 1);
ceOid = CeWriteRecordProps(m_hDB,0,PROPERTY_NUM,pRecordVal);
if (ceOid == 0)
{
TRACE(_T("CEDataBase013:添加数据失败\n"));
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------
//【函数介绍】: BOOL Modify(DWORD dwID,DATA_RECORD * pRecord)
// 编辑指定ID的数据内容
//【入口参数】: (无)
//
//【出口参数】: (无)
//【返回 值】: 返回TRUE为成功,返回FALSE为失败
//---------------------------------------------------------------------
BOOL CEDataBase::Modify(DWORD dwID,DATA_RECORD * pRecord)
{
CEOID ceOid = 0;
CEPROPVAL *pRecordVal = new CEPROPVAL[PROPERTY_NUM];
WORD wProps = 0;
DWORD dwRecSize = 0;
char * pRecNew = (char *)pRecord;
///
ceOid = CeSeekDatabase(m_hDB,CEDB_SEEK_BEGINNING,dwID,&dwRecSize);
ASSERT(ceOid !=0);
for(int i=0; i<PROPERTY_NUM; i++)
{
memset(pRecordVal,0,sizeof(CEPROPVAL));
pRecordVal->propid = PROPERTY_TYPE_ID[i];
switch(PROPERTY_TYPE[i])
{
case PRO_STRING:
{
pRecordVal->val.lpwstr = (wchar_t *)(pRecNew+PROPERTY_POSITION[i]);
break;
}
case PRO_TIME:
{
memcpy((void *)&(pRecordVal->val.filetime),(void *)(pRecNew+PROPERTY_POSITION[i]),sizeof(FILETIME));
break;
}
//升级备注:其他数据类型的case在此添加
}
pRecordVal++;
}
pRecordVal = pRecordVal - PROPERTY_NUM;
ceOid = CeWriteRecordProps(m_hDB,ceOid,PROPERTY_NUM,pRecordVal);
if (ceOid == 0)
{
TRACE(_T("CEDataBase014:修改数据失败\n"));
return FALSE;
}
return TRUE;
}