📄 cedbase.cpp
字号:
/*
*Copyright (c)2001,北京恒基伟业
*All rights reserved.
*
*文件名称:CEdbase.cpp
*文件标识:见配置管理计划书
*摘 要:WinCE数据库类的定义,主要实现WinCE数据库底层API的
* 封装屏蔽细节操作,使其成为一个整体。
*
*
*当前版本:1.1
*作 者:钟元欢
*完成日期:2001 年12 月20 日
*
*取代版本:1.0
*原 作 者:钟元欢
*完成日期:2001 年12 月16 日
*/
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CEdbase.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCEdbase::CCEdbase()
{
m_isReady = FALSE;
m_oidDB = 0;
m_oidDBase = 0;
m_pBuff = 0;
m_hDB = 0;
m_dwIndex = 0;
}
CCEdbase::~CCEdbase()
{
}
//FUNCTION:从当前的数据卷中打开指定的数据库
//PARAMETERS
// lpszName: [in]数据库文件名
// hwndNotify: [in]数据库改动后通知哪个窗口
//RETURN:
// = TRUE 成功
// = FALSE 失败
BOOL CCEdbase::OpenDB(LPWSTR lpszName, HWND hwndNotify)
{
CENOTIFYREQUEST cenr;
cenr.dwSize = sizeof(cenr);
cenr.hwnd = hwndNotify;
cenr.dwFlags = 0;
cenr.hHeap = 0;
cenr.dwParam = 0;
//以第一个字段排序,记录指针不自动移动方式打开数据库
m_hDB = CeOpenDatabaseEx(&m_guid, &m_oidDBase,
lpszName, ID_ORDER_PROP, 0, &cenr);
return m_hDB == INVALID_HANDLE_VALUE ? FALSE : TRUE;
}
//FUNCTION:创建数据库文件
//PARAMETERS
// lpszName: [in]数据库名
//RETURN:
// = TRUE 成功
// = FALSE 失败
BOOL CCEdbase::CreateDB(LPTSTR lpszName)
{
CEDBASEINFO dbi;
dbi.rgSortSpecs[0].propid = ID_ORDER_PROP;
dbi.rgSortSpecs[0].dwFlags = 0;
dbi.dwFlags = CEDB_VALIDCREATE;
lstrcpy(dbi.szDbaseName, lpszName);
dbi.dwDbaseType = 0; //MY_DBASE_TYPE;
dbi.wNumSortOrder = 1; // order by field1
m_oidDBase = CeCreateDatabaseEx(&m_guid, &dbi);
return m_oidDBase == 0 ? FALSE : TRUE;
}
//FUNCTION:
// 初始化数据库,打开指定的数据卷中的数据库,如果不存在则新建一个并打开
//PARAMETERS
// lpszVolName: [in]数据卷名
// lpszDBName: [in]数据库文件名
// hwndNotify: [in]要通告的窗口句柄
//RETURN:
// = TRUE 成功
// = FALSE 失败
BOOL CCEdbase::InitDB(LPWSTR lpszVolName,
LPWSTR lpszDBName,
HWND hwndNotify)
{
//打开数据卷,如果没有则会新建一个,再打开其中的数据库
//如果没有则新建并将其打开
m_isReady = FALSE;
if(!CeMountDBVol(&m_guid, lpszVolName, OPEN_ALWAYS))
{
return FALSE;
}
m_oidDBase = 0;
if(!OpenDB(lpszDBName, hwndNotify))
{
if(CreateDB(lpszDBName))
{
if(!OpenDB(lpszDBName, hwndNotify))
{
return FALSE;
}
}
else
{
return FALSE;
}
}
m_isReady = TRUE;
return TRUE;
}
//FUNCTION:读取当前记录
//PARAMETERS
// lpcPropID: [out]读取的属性(字段)个数(CEPROPVAL数组)
// llpbBuf: [out]CEPROPVAL数组缓冲区指针
//RETURN:
// ID_SUCCESSFULLY: 成功
// ID_NULL_ERROR: 数据库为空
// ID_READ_ERROR: 读取时失败
// ID_NO_READY_ERROR: 数据库未初始化
//REMARK:
// 缓冲区由函数内部自动分配,因此用完后请一定用LocalFee()释放内存。
WORD CCEdbase::ReadRecord(LPWORD lpcPropID, LPBYTE * llpbBuf)
{
DWORD dwRecSize; //存放返回的记录尺寸
CEOID tempid;
if(m_isReady)
{
//数据库为空
if(m_oidDB == 0)
return ID_NULL_ERROR;
m_pBuff = 0;
//读取当前记录
tempid = CeReadRecordProps(m_hDB, CEDB_ALLOWREALLOC,
lpcPropID, NULL, &(LPBYTE)m_pBuff, &dwRecSize);
if(tempid == 0)
return ID_READ_ERROR;
m_oidDB = tempid;
*llpbBuf = (LPBYTE)m_pBuff;
return ID_SUCCESSFULLY;
}
return ID_NO_READY_ERROR;
}
//FUNCTION:新增一条记录并定位到新增记录,数据库按关键属性升序排列
//PARAMETERS:
// cPropID: [in]数组个数
// rcPropVal: [in]CEPROPVAL数组缓冲区指针
//RETURN:
// ID_SUCCESSFULLY 写入成功
// ID_NO_KEY_ERROR 关键字为空
// ID_SAME_KEY_ERROR 存在相同关键字
// ID_WRITE_ERROR 写入时失败
// ID_NO_READY_ERROR 数据库没有初始化
WORD CCEdbase::WriteRecord(WORD cPropID, CEPROPVAL *rgPropVal)
{
WORD i = 0;
CEOID tempid;
DWORD tempIndex;
if(m_isReady)
{
//必须有关键属性写入
while(i < cPropID)
{
if((rgPropVal + i)->propid == ID_ORDER_PROP)
{
break;
}
i++;
}
if(i >= cPropID)
{
return ID_NO_KEY_ERROR;
}
//查找是否有相同的关键属性值,不能有两条相同关键属性值
//的记录存在
CeSeekDatabase(m_hDB, CEDB_SEEK_BEGINNING, 0, &tempIndex);
tempid = CeSeekDatabase(m_hDB, CEDB_SEEK_VALUEFIRSTEQUAL,
(DWORD)(rgPropVal + i), &tempIndex);
if(tempid != 0)
{
return ID_SAME_KEY_ERROR;
}
//新增一条记录
tempid = CeWriteRecordProps(m_hDB, 0, cPropID, rgPropVal);
if(tempid == 0)
{
return ID_WRITE_ERROR;
}
//指向新增的记录
m_oidDB = CeSeekDatabase(m_hDB, CEDB_SEEK_CEOID,
tempid, &m_dwIndex);
return ID_SUCCESSFULLY;
}
return ID_NO_READY_ERROR;
}
//FUNCTION:修改当前记录,如果修改了关键属性记录的先后位置会因自动排序而改变,
//
//PARAMETERS:
// cPropID: [in]数组个数
// rcPropVal: [in]CEPROPVAL数组缓冲区指针
//RETURN:
// ID_SUCCESSFULLY 写入成功
// ID_NO_KEY_ERROR 关键字为空
// ID_SAME_KEY_ERROR 存在相同关键字
// ID_WRITE_ERROR 写入时失败
// ID_NO_READY_ERROR 数据库没有初始化
WORD CCEdbase::ModifyCurRecord(WORD cPropID, CEPROPVAL *rgPropVal)
{
WORD i = 0;
CEOID tempid;
DWORD tempIndex;
if(m_isReady){
//当前纪录指针为空说明数据库为空
if(m_oidDB == 0)
{
return ID_NULL_ERROR;
}
//必须有关键属性写入
while(i < cPropID)
{
if((rgPropVal + i)->propid == ID_ORDER_PROP)
break;
i++;
}
if(i >= cPropID)
{
return ID_NO_KEY_ERROR;
}
//查找是否有相同的关键属性(可以与本身相同)
CeSeekDatabase(m_hDB, CEDB_SEEK_BEGINNING, 0, &tempIndex);
tempid = CeSeekDatabase(m_hDB, CEDB_SEEK_VALUEFIRSTEQUAL,
(DWORD)(rgPropVal + i), &tempIndex);
if(tempid != 0 && tempid != m_oidDB) //数据库已经存在两个
{ //以上记录有相同的关键属性
return ID_BAD_DATA_ERROR; //数据库可能已被破坏
}
//修改当前记录
tempid = CeWriteRecordProps(m_hDB, m_oidDB, cPropID, rgPropVal);
if(tempid == 0)
{
return ID_WRITE_ERROR;
}
//重新指向修改后的记录(记录顺序可能改变)
m_oidDB = CeSeekDatabase(m_hDB, CEDB_SEEK_CEOID,
tempid, &m_dwIndex);
return ID_SUCCESSFULLY;
}
return ID_NO_READY_ERROR;
}
//FUNCTION:删除当前记录
//RETURN:
// ID_SUCCESSFULLY 写入成功
// ID_DEL_ERROR 删除时失败
// ID_NO_READY_ERROR 数据库没有初始化
//REMARK:
// 如果删除成功,后一条记录成为当前记录。如果没有后一条记录,当前记录
// 是最后一条记录。如果数据库删空时。当前记录为空。
WORD CCEdbase::DelRecord()
{
CEOID tempid;
DWORD tempIndex;
if(m_isReady)
{
//当前数据库是否为空
if(m_oidDB == 0)
{
return ID_NULL_ERROR;
}
//得到后面一条记录的id
tempid = CeSeekDatabase(m_hDB, CEDB_SEEK_CURRENT, 1, &tempIndex);
//删除当前记录
if(!CeDeleteRecord(m_hDB, m_oidDB))
{
return ID_DEL_ERROR;
}
//新的当前记录是下一条记录或最后一条记录
if(tempid == 0)
{
tempid = CeSeekDatabase(m_hDB, CEDB_SEEK_END, 0, &m_dwIndex);
}
else
{
tempid = CeSeekDatabase(m_hDB, CEDB_SEEK_CEOID, tempid, &m_dwIndex);
}
//当没有后继记录又没有最后一条记录说明数据库已经删空
m_oidDB = tempid;
return ID_SUCCESSFULLY;
}
return ID_NO_READY_ERROR;
}
//FUNCTION:关闭数据库
void CCEdbase::CloseDB()
{
if(m_isReady && m_hDB !=0 )
{
CloseHandle(m_hDB);
}
CeUnmountDBVol(&m_guid);
m_isReady = FALSE;
return;
}
//FUNCTION:移动记录指针(查找),失败后记录指针位置不变
BOOL CCEdbase::SeekRecord(DWORD dwSeekType, DWORD dwValue)
{
CEOID tempid;
DWORD tempIndex;
if(m_isReady)
{
tempid = CeSeekDatabase(m_hDB, dwSeekType, dwValue, &tempIndex);
if(tempid == 0)
return FALSE;
m_oidDB = tempid;
m_dwIndex = tempIndex;
return TRUE;
}
return FALSE;
}
//FUNCTION:得到当前记录总数
DWORD CCEdbase::GetCurRecrodNum()
{
CEOIDINFO oidinfo;
if(m_isReady)
{
CeOidGetInfoEx(&m_guid, m_oidDBase, &oidinfo);
return oidinfo.infDatabase.wNumRecords;
}
return 0;
}
//FUNCTION:得到当前记录索引
DWORD CCEdbase::GetCurIndex()
{
return m_dwIndex;
}
//FUNCTION::
// 查找含有匹配的属性的记录,找到后的记录成为当前记录否则当前记录不变。
// 每条记录都必须包含完全相同的属性
//PARAMETERS:
// propid: [in]属性ID
// val: [in]属性值
// bFinNext: [in] =TRUE从下一条记录开始查找,=FALSE从当前记录开始查找
//RETURN:
// ID_SUCCESSFULLY: 查找成功
// ID_NO_READY_ERROR: 数据库没有初始化
// ID_NULL_ERROR: 数据库为空
// ID_READ_ERROR: 读失败
// ID_UNSUPPORT_PROP: 不支的属性类型,当前只支持LPTSTR和DWORD型
// ID_NO_FOUND: 没有找到
WORD CCEdbase::Seek(CEPROPID propid, CEVALUNION *val, BOOL bFindNext)
{
DWORD dwRecSize, tempIndex = m_dwIndex;
CEOID tempid;
WORD wPropCount = 1;
CEPROPID key[1];
PCEPROPVAL pRecord;
//数据库还没有初始化
if(!m_isReady)
{
return ID_NO_READY_ERROR;
}
//数据库为空,不进行查询
if(m_oidDB == 0)
{
return ID_NULL_ERROR;
}
key[0] = propid;
if(bFindNext)
{
goto FIND_NEXT;
}
//读取当前记录
m_pBuff = 0;
tempid = CeReadRecordProps(m_hDB, CEDB_ALLOWREALLOC,
&wPropCount, key, &(LPBYTE)m_pBuff, &dwRecSize);
if(tempid == 0)
{
return ID_READ_ERROR;
}
do{
pRecord = (PCEPROPVAL)m_pBuff;
//比较属性是否匹配
if(_tcscmp(pRecord->val.lpwstr, val->lpwstr) == 0)
{
m_oidDB = tempid;
m_dwIndex = tempIndex;
return ID_SUCCESSFULLY;
}
LocalFree(m_pBuff);
FIND_NEXT:
//查找下一条记录
tempid = CeSeekDatabase(m_hDB, CEDB_SEEK_CURRENT, 1, &tempIndex);
if(tempid == 0) //所有的记录都已经查找完毕
{
break;
}
//读取当前记录
m_pBuff = 0;
tempid = CeReadRecordProps(m_hDB, CEDB_ALLOWREALLOC,
&wPropCount, key, &(LPBYTE)m_pBuff, &dwRecSize);
if(tempid == 0)
{
return ID_READ_ERROR;
}
}while(tempid != 0);
CeSeekDatabase(m_hDB, CEDB_SEEK_CEOID, m_oidDB, &m_dwIndex);
return ID_NO_FOUND;
}
//删除所有的记录
WORD CCEdbase::ClearAllRecord()
{
if(!SeekRecord(CEDB_SEEK_BEGINNING, 0))
{
return ID_SUCCESSFULLY;
}
while(DelRecord() == ID_SUCCESSFULLY)
{
;
}
return ID_SUCCESSFULLY;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -