📄 cdatamanage.cpp
字号:
/*
*Copyright (c)2001,北京恒基伟业
*All rights reserved.
*
*文件名称:CDataManage.cpp
*文件标识:见配置管理计划书
*摘 要:WinCE数据管理模块类的定义,主要实现WinCE数据库通用的
* 数据存储、读取、检索的功能
*
*
*当前版本:1.1
*作 者:钟元欢
*完成日期:2001 年12 月20 日
*
*取代版本:1.0
*原 作 者:钟元欢
*完成日期:2001 年12 月16 日
*/
#include "..\stdafx.h"
#include "CDataManage.h"
#include "Csv.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//构成
CDataManage::CDataManage(const struct FieldType &fieldType)
{
Init(fieldType);
}
//析构
CDataManage::~CDataManage()
{
TransferData(FALSE); //将记录缓冲区的数据回写
m_selfCigdata.CloseDB(); //关闭数据库,数据卷
}
///////////////////////////////////////////////////////////////////////////////////////
//FUNCTION:
// 初始化数据库
//PARAMETERS:
// strVolName: [in]数据卷名称
// strDBName: [in]数据库名称
// wPropNum: [in]属性个数
// pList: [in]属性ID列表
//RETURN:
// ID_SUCCESSFULLY 执行成功
// 具体错误代码请参见RetCodeInfo.h
WORD CDataManage::Init(const struct FieldType &fieldType)
{
WORD i;
WORD retCode;
m_volName = fieldType.strVolName;
m_dbName = fieldType.strDBName;
m_propNum = fieldType.wFieldNum + 1;
m_wNextRecordNum = 10000;
m_bReloadFlag = TRUE;
m_propidList[0] = FIELD_TYPE_STR; //第一个字段被占用为key
for(i = 1; i < m_propNum; i++) //字段属性列表
{
m_propidList[i] = fieldType.wFieldType[i - 1];
if(m_propidList[i] != FIELD_TYPE_STR && m_propidList[i] != FIELD_TYPE_LONG
&& m_propidList[i] != FIELD_TYPE_DOT && m_propidList[i] != FIELD_TYPE_DATE)
{
::AfxMessageBox(_T("属性列表错误!"), MB_OK, NULL);
return ID_PARAM_ERROR;
}
}
m_modifyFlag = FALSE; //修改标志reset
ClearRamData(); //成员变量清空
//打开数据库
retCode = m_selfCigdata.InitDB(m_volName.GetBuffer(50),
m_dbName.GetBuffer(50), NULL);
m_volName.ReleaseBuffer();
m_dbName.ReleaseBuffer();
if(!retCode)
{
::AfxMessageBox(_T("数据库初始化失败!"), MB_OK, NULL);
return ID_OPEN_ERROR;
}
//如果数据库不为空就将第一条记录读入内存缓冲区
if(m_selfCigdata.GetCurRecrodNum() != 0)
{
if(!m_selfCigdata.SeekRecord(CEDB_SEEK_END, 0))
{
::AfxMessageBox(_T("复位到最后一条记录失败!"), MB_OK, NULL);
return ID_SEEK_ERROR;
}
retCode = TransferData(TRUE);
if(retCode != ID_SUCCESSFULLY)
{
::AfxMessageBox(_T("数据导入内存失败!"), MB_OK, NULL);
return retCode;
}
m_wNextRecordNum = _ttol(m_propData[0]);
if(!m_selfCigdata.SeekRecord(CEDB_SEEK_BEGINNING, 0))
{
::AfxMessageBox(_T("复位到首记录失败!"), MB_OK, NULL);
return ID_SEEK_ERROR;
}
retCode = TransferData(TRUE);
if(retCode != ID_SUCCESSFULLY)
{
::AfxMessageBox(_T("数据导入内存失败!"), MB_OK, NULL);
return retCode;
}
}
return ID_SUCCESSFULLY;
}
///////////////////////////////////////////////////////////////////////////////////////
//FUNCTION:
// 查找指定的属性的内容与指定字符串匹配的记录,并将其设为当前记录,
// 如果没有匹配的记录则当前记录不变
//PARAMETERS:
// propid: [in]字段索引
// strVal: [in]匹配字符串
// bFindNext: [in]TRUE从下一条记录开始查找,FALSE从当前记录开始查找
//RETURN:
// ID_SUCCESSFULLY: 查找成功
// ID_NO_READY_ERROR: 数据库没有初始化
// ID_NULL_ERROR: 数据库为空
// ID_READ_ERROR: 读失败
// ID_NO_FOUND: 没有找到
WORD CDataManage::SeekByPropID(WORD propid, const CString &strVal, BOOL bFindNext, WORD compType)
{
WORD wRetCode;
//字段ID是否正确
if(propid < 0 || propid >= m_propNum)
{
return ID_PROPID_ERROR;
}
//字段类型是否匹配
if(GetPropType(propid) != FIELD_TYPE_STR)
{
return ID_TYPE_ERROR;
}
//当前记录总数为0则不用查找
if(GetCurRecrodNum() == 0)
{
return ID_NULL_ERROR;
}
//如果匹配字符串为空则不用查找
if(strVal == _T(""))
{
return ID_NULL_ERROR;
}
//确定查找的开始位置
if(bFindNext)
{
goto FIND_NEXT;
}
//查找
do{
if(CompareVal(propid, compType, strVal))
{
return ID_SUCCESSFULLY;
}
FIND_NEXT:
wRetCode = Seek(CEDB_SEEK_CURRENT, 1);
}while(wRetCode == ID_SUCCESSFULLY);
return wRetCode;
}
//FUNCTION:
// 查找指定的属性的内容与指定数字匹配的记录,并将其设为当前记录,
// 如果没有匹配的记录则当前记录不变
//PARAMETERS:
// propid: [in]字段索引
// lVal: [in]要匹配的数字
// bFindNext: [in]TRUE从下一条记录开始查找,FALSE从当前记录开始查找
//RETURN:
// ID_SUCCESSFULLY: 查找成功
// ID_NO_READY_ERROR: 数据库没有初始化
// ID_NULL_ERROR: 数据库为空
// ID_READ_ERROR: 读失败
// ID_NO_FOUND: 没有找到
WORD CDataManage::SeekByPropID(WORD propid, LONG lVal, BOOL bFindNext, WORD compType)
{
WORD wRetCode;
//字段ID是否正确
if(propid < 0 || propid >= m_propNum)
{
return ID_PROPID_ERROR;
}
//字段类型是否匹配
if(GetPropType(propid) != FIELD_TYPE_LONG)
{
return ID_TYPE_ERROR;
}
//当前记录总数为0则不用查找
if(GetCurRecrodNum() == 0)
{
return ID_NULL_ERROR;
}
//确定查找的开始位置
if(bFindNext)
{
goto FIND_NEXT;
}
//查找
do{
if(CompareVal(propid, compType, lVal))
{
return ID_SUCCESSFULLY;
}
FIND_NEXT:
wRetCode = Seek(CEDB_SEEK_CURRENT, 1);
}while(wRetCode == ID_SUCCESSFULLY);
return wRetCode;
}
WORD CDataManage::SeekByPropID(WORD propid, FLOAT fVal, BOOL bFindNext, WORD compType)
{
WORD wRetCode;
//字段ID是否正确
if(propid < 0 || propid >= m_propNum)
{
return ID_PROPID_ERROR;
}
//字段类型是否匹配
if(GetPropType(propid) != FIELD_TYPE_DOT)
{
return ID_TYPE_ERROR;
}
//当前记录总数为0则不用查找
if(GetCurRecrodNum() == 0)
{
return ID_NULL_ERROR;
}
//确定查找的开始位置
if(bFindNext)
{
goto FIND_NEXT;
}
//查找
do{
if(CompareVal(propid, compType, fVal))
{
return ID_SUCCESSFULLY;
}
FIND_NEXT:
wRetCode = Seek(CEDB_SEEK_CURRENT, 1);
}while(wRetCode == ID_SUCCESSFULLY);
return wRetCode;
}
WORD CDataManage::SeekByPropID(WORD propid, const CTime &tVal, BOOL bFindNext, WORD compType)
{
WORD wRetCode;
//字段ID是否正确
if(propid < 0 || propid >= m_propNum)
{
return ID_PROPID_ERROR;
}
//字段类型是否匹配
if(GetPropType(propid) != FIELD_TYPE_DATE)
{
return ID_TYPE_ERROR;
}
//当前记录总数为0则不用查找
if(GetCurRecrodNum() == 0)
{
return ID_NULL_ERROR;
}
//确定查找的开始位置
if(bFindNext)
{
goto FIND_NEXT;
}
//查找
do{
if(CompareVal(propid, compType, tVal))
{
return ID_SUCCESSFULLY;
}
FIND_NEXT:
wRetCode = Seek(CEDB_SEEK_CURRENT, 1);
}while(wRetCode == ID_SUCCESSFULLY);
return wRetCode;
}
////////////////////////////////////////////////////////////////////////////////////////
//FUNCTION:
// 移动记录指针,并将其设为当前记录,如果失败则当前记录不变
//PARAMETERS:
// dwSeekType: [in]移动方式CEDB_SEEK_CURRENT
// dwValue: [in]向前或向后移动的记录数,>0向后移,<0向前移
//RETURN:
// ID_SUCCESSFULLY: 查找成功
// 具体错误代码请参见RetCodeInfo.h
WORD CDataManage::Seek(DWORD dwSeekType, DWORD dwValue)
{
WORD retCode;
//从内存变量传送数据到数据库(保存当前记录)
retCode = TransferData(FALSE);
if(retCode != ID_SUCCESSFULLY)
{
return retCode;
}
//定位到新的记录
if(!m_selfCigdata.SeekRecord(dwSeekType, dwValue))
{
return ID_SEEK_ERROR;
}
//从数据库传送数据到内存变量(读取记录)
return TransferData(TRUE);
}
//FUNCTION:
// 删除当前记录
//PARAMETERS:
// 无
//RETURN:
// ID_SUCCESSFULLY: successfully
// 具体错误代码请参见RetCodeInfo.h
WORD CDataManage::DelCurRecord()
{
WORD wRetCode;
wRetCode = m_selfCigdata.DelRecord();
if(wRetCode != ID_SUCCESSFULLY)
{
return wRetCode;
}
wRetCode = TransferData(TRUE);
return wRetCode == ID_NULL_ERROR ? //数据库被删空
ID_SUCCESSFULLY : wRetCode;
}
//FUNCTION:
// 增加一条空记录
//PARAMETERS:
// 无
//RETURN:
// ID_SUCCESSFULLY: successfully
// 具体错误代码请参见RetCodeInfo.h
WORD CDataManage::AddNewRecord()
{
WORD retCode;
WORD i;
//空数据库
if(GetCurRecrodNum() == 0) //自动生成索引字(第一个字段)
{
m_propData[0] = _T("10000"); //从10000开始计算,可保证长度一致
}
else
{
//从内存变量传送数据到数据库(保存当前记录)
retCode = TransferData(FALSE);
if(retCode != ID_SUCCESSFULLY)
{
return retCode;
}
m_wNextRecordNum++;
if(m_wNextRecordNum > MAX_RECORD_NUM)
{
return ID_MUCH_RECORD;
}
m_propData[0].Format(_T("%ld"), m_wNextRecordNum);
m_propData[0].ReleaseBuffer();
}
//设置刷新和修改标志
m_bReloadFlag = TRUE;
m_modifyFlag = FALSE;
//清空内存,新增一条新的记录
for(i = 1; i < m_propNum; i++)
{
m_propData[i] = _T("");
m_propData[i].ReleaseBuffer();
}
return RamToDisk(TRUE);
}
/////////////////////////////////////////////////////////////////////////////////////////
//FUNCTION:
// 得到当前记录总数
//PARAMETERS:
// 无
//RETURN:
// 当前记录总数(>=0)
DWORD CDataManage::GetCurRecrodNum()
{
return m_selfCigdata.GetCurRecrodNum();
}
//FUNCTION:
// 得到当前记录索引
//PARAMETERS:
// 无
//RETURN:
// 当前记录的位置(>=0)
DWORD CDataManage::GetCurIndex()
{
return m_selfCigdata.GetCurIndex();
}
//FUNCTION:
// 得到字段数
//PARAMETERS:
// 无
//RETURN:
// 字段数
WORD CDataManage::GetPropNum()
{
return m_propNum - 1;
}
//得到某一字段的类型
WORD CDataManage::GetPropType(WORD propid)
{
return m_propidList[propid + 1];
}
////////////////////////////////////////////////////////////////////////////////////
//FUNCTION:
// 在内存缓冲和数据库之间传送数据
//PARAMETERS:
// direction: [in]TRUE数据库->内存变量,FALSE内存变量->数据库
//RETURN:
// ID_SUCCESSFULLY: successfully
// 具体错误代码请参见RetCodeInfo.h
WORD CDataManage::TransferData(BOOL direction)
{
if(direction)
{
m_modifyFlag = FALSE;
return DiskToRam();
}
else if(m_modifyFlag) //数据没有被修改则
{ //则不需写回
m_modifyFlag = FALSE;
return RamToDisk(FALSE);
}
return ID_SUCCESSFULLY;
}
//FUNCTION:
// 将数据从数据库读入内存缓冲区
//PARAMETERS:
// 无
//RETURN:
// ID_SUCCESSFULLY 执行成功
// 具体错误代码请参见RetCodeInfo.h
WORD CDataManage::DiskToRam()
{
WORD i, j, retCode;
PBYTE pBuff;
PCEPROPVAL pRecord;
WORD wPropIDCount;
ClearRamData();
//读取记录
retCode = m_selfCigdata.ReadRecord(&wPropIDCount, &pBuff);
if(retCode != ID_SUCCESSFULLY)
{
return retCode;
}
if(!pBuff)
{
return ID_READ_ERROR;
}
pRecord = (PCEPROPVAL)pBuff;
//填写内存记录缓冲区
for(i = 0; i < wPropIDCount; i++)
{
j = 0;
while((MAKELONG(CEVT_LPWSTR, j) != pRecord->propid) && j < m_propNum)
{
j++;
}
if(j < m_propNum)
{
m_propData[j] = pRecord->val.lpwstr;
}
pRecord++;
}
LocalFree(pBuff);
return ID_SUCCESSFULLY;
}
//FUNCTION:
// 将缓冲区的数据写入数据库
//PARAMETERS:
// newFlag: [in]TRUE以新增方式写入,FALSE以修改方式写入
//RETURN:
// ID_SUCCESSFULLY 执行成功
// 具体错误代码请参见RetCodeInfo.h
WORD CDataManage::RamToDisk(BOOL newFlag)
{
WORD i;
WORD strLen;
WORD retCode;
CEPROPVAL propVal[MAX_PROP_NUM];
for(i = 0; i < m_propNum; i++) //全部保存为字符串型
{
propVal[i].propid = MAKELONG(CEVT_LPWSTR, i);
propVal[i].wLenData = NULL;
propVal[i].wFlags = NULL;
strLen = (m_propData[i].GetLength() + 1) * sizeof(TCHAR);
propVal[i].val.lpwstr = m_propData[i].GetBuffer(strLen);
}
if(newFlag) //新增方式写入
{
retCode = m_selfCigdata.WriteRecord(m_propNum, propVal);
}
else //修改方式写入
{
retCode = m_selfCigdata.ModifyCurRecord(m_propNum, propVal);
}
return retCode;
}
//FUNCTION:
// 清除内存中的数据
//PARAMETERS:
// 无
//RETURN:
// 无
void CDataManage::ClearRamData()
{
WORD i;
for(i = 0; i < m_propNum; i++)
{
m_propData[i] = _T("");
m_propData[i].ReleaseBuffer();
}
return;
}
///////////////////////////////////////////////////////////////////////////////////////
//得到当前记录指定属性的内容
//FUNCTION:
// 得到当前记录指定属性的内容
//PARAMETERS:
// propid: [in]属性ID
// strData:[out]属性内容
// ID_SUCCESSFULLY: 成功
// ID_PROPID_ERROR: 参数错误
WORD CDataManage::GetPropData(WORD propid, CString &strData)
{
if(propid < 0 || propid >= m_propNum)
{
return ID_PROPID_ERROR;
}
propid++;
if(m_propidList[propid] != FIELD_TYPE_STR) //字段类型不匹配
{
return ID_TYPE_ERROR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -