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

📄 dbstudent.cpp

📁 在Windows mobile6下的一个简单的EDB数据库创建添加查询等功能
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*-----------------------------------------
* Copyright (c) 2008 Eric Wong
* 本版紧供读者参考,不得用于任何商业行为
*
* 文件名称: DBStudent.cpp
* 文件标识: 
* 摘要: 封装学生数据库
*
* 当前版本: 1.0
* 作者: 汪兵 Eric Wong
* 完成日期: 2008年1月6日
*
* 取代版本:
* 原作者: 
* 完成日期: 
----------------------------------------*/
#include "StdAfx.h"
#include "DBStudent.h"

//构造函数
CDBStudent::CDBStudent(void)
{
	ZeroMemory(&m_VolGUID,sizeof(m_VolGUID));	//存储数据库文件卷标识
	m_hDB = INVALID_HANDLE_VALUE;				//存储数据库句柄
	m_ceOid = 0;								//存储数据库对象标识
	m_hSession = INVALID_HANDLE_VALUE;			//会话句柄
}

//析构函数
CDBStudent::~CDBStudent(void)
{
}

/*--------------------------------------------------------------------
【函数介绍】:  在数据库卷中,新建数据库
【入口参数】:	pCeGuid : 数据库卷ID
				strDBName : 数据库名
【出口参数】:  
【返回  值】:  TRUE:成功; FALSE:失败
---------------------------------------------------------------------*/
BOOL CDBStudent::DB_Create_Student(  CEGUID * pCeGuid, /*数据库文件卷名称*/
							const LPCTSTR strDBName /*数据库名称*/)
{
	//定义数据库基本信息
	CEDBASEINFOEX     DBInfo;
	//填充DBInfo信息
	memset(&DBInfo, 0, sizeof(CEDBASEINFOEX)) ;
	DBInfo.wVersion = CEDBASEINFOEX_VERSION;  //版本
	DBInfo.dwFlags |= CEDB_VALIDDBFLAGS | CEDB_VALIDNAME | CEDB_VALIDSORTSPEC; //标识
	DBInfo.wNumSortOrder = 2;   //索引个数
	wcscpy(DBInfo.szDbaseName , DBTABLENAME);  //数据库名
	//定义第1个排序方式
	DBInfo.rgSortSpecs[0].wVersion = SORTORDERSPECEX_VERSION;
	DBInfo.rgSortSpecs[0].wNumProps = 1;
	//指定PID_NO为唯一索引
	DBInfo.rgSortSpecs[0].wKeyFlags = CEDB_SORT_UNIQUE;
	DBInfo.rgSortSpecs[0].rgPropID[0] = PID_NO;		  //学生编号
	DBInfo.rgSortSpecs[0].rgdwFlags[0] = CEDB_SORT_DESCENDING;

	//定义第2个排序方式
	DBInfo.rgSortSpecs[1].wVersion = SORTORDERSPECEX_VERSION;
	DBInfo.rgSortSpecs[1].wNumProps = 1;
	DBInfo.rgSortSpecs[1].wKeyFlags = 0;
	DBInfo.rgSortSpecs[1].rgPropID[0] = PID_NAME;   //学生姓名
	DBInfo.rgSortSpecs[1].rgdwFlags[0] = CEDB_SORT_DESCENDING;

	//设置字段属性
	CEPROPSPEC dbPropInfo[5];
	//学生编号
	dbPropInfo[0].wVersion = 1;
	dbPropInfo[0].propid = PID_NO;
	dbPropInfo[0].pwszPropName = L"编号";
	dbPropInfo[0].cchPropName = wcslen(dbPropInfo[0].pwszPropName);
	dbPropInfo[0].dwFlags = 0;
	//学生姓名
	dbPropInfo[1].wVersion = 1;
	dbPropInfo[1].propid = PID_NAME;
	dbPropInfo[1].pwszPropName = L"姓名";
	dbPropInfo[1].cchPropName = wcslen(dbPropInfo[1].pwszPropName);
	dbPropInfo[1].dwFlags = 0;
	//出生日期
	dbPropInfo[2].wVersion = 1;
	dbPropInfo[2].propid = PID_BIRTHDAY;
	dbPropInfo[2].pwszPropName = L"出生日期";
	dbPropInfo[2].cchPropName = wcslen(dbPropInfo[2].pwszPropName);
	dbPropInfo[2].dwFlags = 0;
	//身高
	dbPropInfo[3].wVersion = 1;
	dbPropInfo[3].propid = PID_STATURE;
	dbPropInfo[3].pwszPropName = L"身高";
	dbPropInfo[3].cchPropName = wcslen(dbPropInfo[3].pwszPropName);
	dbPropInfo[3].dwFlags = 0;

	//照片
	dbPropInfo[4].wVersion = 1;
	dbPropInfo[4].propid = PID_IMAGE;
	dbPropInfo[4].pwszPropName = L"照片";
	dbPropInfo[4].cchPropName = wcslen(dbPropInfo[4].pwszPropName);
	dbPropInfo[4].dwFlags = 0;

	//创建数据库
	m_ceOid = CeCreateDatabaseWithProps(pCeGuid, &DBInfo, 5, dbPropInfo);
	if (m_ceOid == 0)
	{
		TRACE(L"创建数据库失败,The Error Code =%d \n",GetLastError());
		return FALSE;
	}
	//
	return TRUE;
}

/*--------------------------------------------------------------------
【函数介绍】:  获取数据库的记录数目
【入口参数】:  pCeGuid : 数据库文件卷标识指针
			   ceOid   : 数据库对象标识
【出口参数】:  (无)
【返回  值】: -1 :代表失败。成功的话,返回实际的记录数
---------------------------------------------------------------------*/
int CDBStudent::GetRecordCount(CEGUID *pCeGuid,CEOID ceOid)
{
	int iCount;
	CEOIDINFOEX  oidinfo;
    oidinfo.wVersion = CEOIDINFOEX_VERSION;
	//获取数据库信息
	if (!CeOidGetInfoEx2(pCeGuid,ceOid,&oidinfo))
	{
		TRACE(L"获取信息失败\n");
		return -1;
	}

	//判断oidinfo.wObjType是否是数据库类型
	if (oidinfo.wObjType != OBJTYPE_DATABASE)
	{
		return -1;
	}

	//得到记录数
	iCount = oidinfo.infDatabase.dwNumRecords;
	return iCount;
}

/*--------------------------------------------------------------------
【函数介绍】:  打开数据库
【入口参数】:	strVolumeName : 数据库卷文件名
				strDBName : 数据库名
【出口参数】:  
【返回  值】:  TRUE:成功; FALSE:失败
---------------------------------------------------------------------*/
BOOL CDBStudent::DB_Open_Student(const LPCTSTR strVolumeName, /*数据库文件卷名称*/
							const LPCTSTR strDBName /*数据库名称*/)
{
	BOOL bResult = FALSE;
	DWORD dwErrorCode = 0;
	//定义排序方式
    SORTORDERSPECEX rgSortSpecs;
    rgSortSpecs.wVersion = SORTORDERSPECEX_VERSION;
    rgSortSpecs.wNumProps = 1;
    rgSortSpecs.wKeyFlags = CEDB_SORT_UNIQUE;
    rgSortSpecs.rgPropID[0] = PID_NO;
    rgSortSpecs.rgdwFlags[0] = CEDB_SORT_DESCENDING;


	//1、挂载数据库卷,如果存在则打开,不存在,就新建一个
	if (!CeMountDBVolEx(&m_VolGUID,DBFILENAME,NULL,OPEN_ALWAYS))
	{
		TRACE(_T("打开或新建数据卷失败 \n"));
		return FALSE;
	}

	//2,创建会话句柄
    m_hSession = CeCreateSession(&m_VolGUID);

	//3、接着打开数据库
    m_hDB = CeOpenDatabaseInSession( m_hSession,
                            &m_VolGUID, 
                            &m_ceOid, 
                            DBTABLENAME, 
                            &rgSortSpecs, 
                            0,//CEDB_AUTOINCREMENT,
                            NULL) ;	
	if (m_hDB == INVALID_HANDLE_VALUE)
	{
		dwErrorCode = GetLastError();
		//4、如果数据库不存在,就新建之
		if ( dwErrorCode== ERROR_FILE_NOT_FOUND) 
		{
			//创建新数据库
			if (!DB_Create_Student(&m_VolGUID,DBTABLENAME))
			{

				TRACE(L"打开数据库失败\n");
				goto error;
			}
			//5、创建数据库后,应紧接着打开数据库
			m_hDB = CeOpenDatabaseInSession( m_hSession,
									&m_VolGUID, 
									&m_ceOid, 
									DBTABLENAME, 
									&rgSortSpecs, 
									0,//CEDB_AUTOINCREMENT,
									NULL) ;	

			if (m_hDB == INVALID_HANDLE_VALUE)
			{

				TRACE(L"打开数据库失败\n");
				goto error;
			}
		}
		else
		{
			TRACE(L"打开数据库失败\n");
			goto error;
		}
	}

	return TRUE;

error:
	//此处得卸载数据库卷
	if (!CeUnmountDBVol(&m_VolGUID))
	{
		TRACE(_T("卸载数据库文件卷失败"));
	}
	return FALSE;
}

/*--------------------------------------------------------------------
【函数介绍】:  关闭数据库
【入口参数】:  (无)
【出口参数】:  (无)
【返回  值】:  TRUE:成功; FALSE:失败
---------------------------------------------------------------------*/
BOOL CDBStudent::DB_Close_Student()
{
 
	//1、关闭数据库
	if (m_hDB != INVALID_HANDLE_VALUE )
	{
		if (!CloseHandle(m_hDB))
		{
			TRACE(L"关闭数据库失败\n");
			return FALSE;
		}
	}
	//2、将数据库卷的数据缓冲到永久存储介质上
	if ((m_VolGUID.Data1 != 0) 
		|| (m_VolGUID.Data1 != 0) 
		|| (m_VolGUID.Data1 != 0) 
		|| (m_VolGUID.Data1 != 0))
	{
		if (!CeFlushDBVol(&m_VolGUID))
		{
			TRACE(L"缓冲介质失败\n");
			return FALSE;
		}
	}

	//3 、关闭回话对象
	if (m_hSession != INVALID_HANDLE_VALUE )
	{
		if (!CloseHandle(m_hSession))
		{
			TRACE(L"关闭回话对象失败\n");
			return FALSE;
		}
	}

	//4、卸载数据库卷
	if ((m_VolGUID.Data1 != 0) 
		|| (m_VolGUID.Data1 != 0) 
		|| (m_VolGUID.Data1 != 0) 
		|| (m_VolGUID.Data1 != 0))
	{
		if (!CeUnmountDBVol(&m_VolGUID))
		{
			TRACE(L"卸载数据库文件卷失败\n");
			return FALSE ;
		}
	}
	return TRUE;
}


/*--------------------------------------------------------------------
【函数介绍】:  添加一条新记录
【入口参数】:  pRecStudent : 学生数据库表结构
【出口参数】:  (无)
【返回  值】:  TRUE:添加成功;FALSE:添加失败
---------------------------------------------------------------------*/
BOOL CDBStudent::AddNewStudent(const REC_STUDENT *pRecStudent)
{
	//定义学生数据库对象
	CDBStudent tblStudent; 
	CEOID ceOid;
	//定义字段属性
	CEPROPVAL pProps[4];
	DWORD dwErrorCode = 0;

	DWORD dwWritten = 0;
	//定义内存流句柄,用于写入照片数据
	HANDLE hStream = INVALID_HANDLE_VALUE ;

	//1,打开学生数据库
	if (!tblStudent.DB_Open_Student())
	{
		//打开学生数据库失败
		return FALSE;
	}

	//给字段属性赋值
	ZeroMemory(&pProps[0],sizeof(CEPROPVAL)*4);

	//学生学号
	pProps[0].propid = PID_NO; 
	pProps[0].val.lpwstr = LPWSTR(pRecStudent->szNo);
	pProps[0].wFlags = 0;

	//学生姓名
	pProps[1].propid = PID_NAME ; 
	pProps[1].val.lpwstr = LPWSTR(pRecStudent->szName);
	pProps[1].wFlags = 0;

	//学生出生日期
	pProps[2].propid = PID_BIRTHDAY;
	pProps[2].val.filetime  = pRecStudent->ftBirthday;
	pProps[2].wFlags = 0;

	//学生身高
	pProps[3].propid = PID_STATURE;
	pProps[3].val.lVal = pRecStudent->iStature;
	pProps[3].wFlags = 0;

	//写入记录
	ceOid = CeWriteRecordProps(tblStudent.m_hDB,0,4,pProps);

	if (ceOid == 0)
	{
		dwErrorCode = GetLastError();
		//如果 dwErrorCode  = 183, 表示学生编号重复
		if (dwErrorCode == ERROR_ALREADY_EXISTS)
		{
			TRACE(L"学生编号重复\n");
		}
		else
		{
			TRACE(L"写入记录失败 , Error Code = %d \n",dwErrorCode);
		}
		goto error;
	}

	//此时在写入学生照片
	//如果学生照片字段无数据,则返回
	if (pRecStudent->blImage.dwCount == 0)
	{
		//关闭数据库
		tblStudent.DB_Close_Student();
		//
		return TRUE;
	}
	//打开流
	hStream = CeOpenStream(tblStudent.m_hDB,PID_IMAGE,GENERIC_WRITE);

	if (hStream == INVALID_HANDLE_VALUE)
	{
		TRACE(L"打开PID_IMAGE 流失败\n");
		goto error;
	}
	
	//将学生照片数据写入流中
	if (!CeStreamWrite(hStream,pRecStudent->blImage.lpb,pRecStudent->blImage.dwCount,&dwWritten))
	{
		TRACE(L"将学生照片写入流失败\n");
		goto error;
	}

	//保存流数据
	if (!CeStreamSaveChanges(hStream))
	{
		TRACE(L"保存流数据失败\n");
		goto error;
	}

	//最后,关闭打开的流句柄
	CloseHandle(hStream);

	//关闭数据库
	tblStudent.DB_Close_Student();

	return TRUE;
error:
	//关闭数据库
	tblStudent.DB_Close_Student();

	if (hStream != INVALID_HANDLE_VALUE )
	{
		//关闭打开的流句柄
		CloseHandle(hStream);
	}
	return FALSE;
}

/*--------------------------------------------------------------------
【函数介绍】:  编辑记录; 根据学生编号,修改记录
【入口参数】:  strNo : 学生编号
			   pRecStudent : 学生数据库表结构
【出口参数】:  (无)
【返回  值】:  TRUE:编辑成功;FALSE:编辑失败
---------------------------------------------------------------------*/
BOOL CDBStudent::EditStudent(LPCTSTR strNo,const REC_STUDENT *pRecStudent)
{
	//定义学生数据库对象
	CDBStudent tblStudent;
	CEOID tmpCeOid;
	CEOID ceOid;
	DWORD dwIndex = 0;
	DWORD dwWritten = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -