⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdatamanage.cpp

📁 在WinCe平台上开发的数据库管理程序,里面有一个可排序列表控件的实现和Excel的CVS文件的读写类
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 *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 + -