装配数据库卷:BOOL CeMountDBVol( PCEGUID pceguid, LPWSTR lpszDBVol,DWORD dwFlags);
卸载数据库卷:BOOL CeUnmountDBVol(PCEGUID pceguid);
创建数据库:CEOID CeCreateDatabaseEx( PCEGUID pceguid, CEDBASEINFO *lpCEDBInfo);
打开数据库: HANDLE CeOpenDatabaseEx( PCEGUID pceguid, PCEOID poid,LPWSTR lpszName, CEPROPID propid, DWORD dwFlags,CENOTIFYREQUEST *pReq);
写数据库: CEOID CeWriteRecordProps(HANDLE hDbase, CEOID oidRecord, WORD cPropID, CEPROPVAL *rgPropVal),
读数据库: CEOID CeReadRecordPropsEx( HANDLE hDbase, DWORD dwFlags,LPWORD lpcPropID, CEPROPID *rgPropID, LPBYTE *lplpBuffer,LPDWORD lpcbBuffer, HANDLE hHeap);
删除记录:BOOL CeDeleteRecord(HANDLE hDatabase, CEOID oidRecord);
移动指针:CEOID CeSeekDatabaseEx(HANDLE hDatabase,DWORD dwSeekType, DWORD dwValue, WORD wNumVals, LPDWORD lpdwIndex);
EDB是从Windows Mobile 5.0后出现的,提供了比CEDB更好的性能。
要使用EDB,首先就是mount
- BOOL CeMountDBVol(
- PCEGUID pceguid,
- LPWSTR lpszDBVol,
- DWORD dwFlags
- );
它的第一个参数是一个CEGUID类型的指针,也是一种唯一标识符,一般在开始使用前先用CREATE_SYSTEMGUID来将其清0。第二个参数就是数据库卷的卷名,第三个参数就标志,这个标志位的意义与CreateFile的非常类似,其实EDB也是一种特殊的文件。也可以用CeMountDBVolEx函数来挂载卷。
将卷挂上之后,就可以使用CeCreateDatabaseWithProps函数来创建数据库。它的声明如下:
- CEOID CeCreateDatabaseWithProps(
- PCEGUID pGuid,
- CEDBASEINFOEX* pInfo,
- DWORD cProps,
- CEPROPSPEC* prgProps
- );
第一个参数就是CeMountDBVol的第一个参数传回的CEGUID,第二个参数是重点,里面包含了要创建的数据库的结构,即每个属性列的类型等。第三个参数指示了第四个参数的个数。第四个参数是好像是指定属性列的一些其它信息用的(这个也不清楚)。
CEDBASEINFOEX的定义如下:
- typedef struct CEDBASEINFOEX {
- WORD wVersion;
- WORD wNumSortOrder;
- DWORD dwFlags;
- WCHAR szDbaseName[CEDB_MAXDBASENAMELEN];
- DWORD dwDbaseType;
- DWORD dwNumRecords;
- DWORD dwSize;
- FILETIME ftLastModified;
- SORTORDERSPECEX rgSortSpecs[CEDB_MAXSORTORDER];
- } CEDBASEINFOEX;
例如这段代码就创建了一个有两个属性列的数据库,第一个属性是名字,第二个属性是年龄。
- CEDBASEINFOEX dbInfo = {0};
- dbInfo.wVersion = CEDBASEINFOEX_VERSION;
- dbInfo.dwFlags = CEDB_VALIDDBFLAGS | CEDB_VALIDNAME | CEDB_VALIDSORTSPEC;
- dbInfo.wNumSortOrder = 1;
- _tcscpy(dbInfo.szDbaseName, szDbname);
- dbInfo.rgSortSpecs[0].wVersion = SORTORDERSPECEX_VERSION;
- dbInfo.rgSortSpecs[0].wNumProps = 1;
- dbInfo.rgSortSpecs[0].wKeyFlags = 0;
- dbInfo.rgSortSpecs[0].rgPropID[0] = PROP_NAME;
- dbInfo.rgSortSpecs[0].rgdwFlags[0] = CEDB_SORT_UNKNOWNFIRST;
- dbInfo.rgSortSpecs[1].wVersion = SORTORDERSPECEX_VERSION;
- dbInfo.rgSortSpecs[1].wNumProps = 1;
- dbInfo.rgSortSpecs[1].wKeyFlags = 0;
- dbInfo.rgSortSpecs[1].rgPropID[0] = PROP_AGE;
- dbInfo.rgSortSpecs[1].rgdwFlags[0] = CEDB_SORT_UNKNOWNFIRST;
-
- CeCreateDatabaseWithProps(&g_VolGuid, &dbInfo, 0, NULL);
因为rgSortSpecs数组被定义为16,所以EDB的属性列最多也就是16。
当创建好数据库之后,就可以打开数据库了,然后才能进行读写数据库。
要打开数据库,先用CeCreateSession创建一个会话,然后用CeOpenDatabaseInSession来得到一个数据库句柄。
写数据库是通过CeWriteRecordProps函数来实现的。
CeWriteRecordProps的定义如下:
- CEOID CeWriteRecordProps(
- HANDLE hDatabase,
- CEOID oidRecord,
- WORD cPropID,
- CEPROPVAL* prgPropVal
- );
若oidRecord为0,则新添加的记录直接追加到最后。最后一个参数是用来填充属性的数据。
要写数据库,示例代码如下:
- prop[0].propid = PROP_NAME;
- prop[0].val.lpwstr = _T("某某");
- prop[0].wFlags = 0;
- prop[1].propid = PROP_AGE;
- prop[1].val.uiVal = 25;
- prop[1].wFlags = 0;
- CeWriteRecordProps(hdb, 0, 2, prop);
要想读数据库,只要用CeReadRecordPropsEx函数即可。
它的定义如下:
- CEOID CeReadRecordPropsEx(
- HANDLE hDatabase,
- DWORD dwFlags,
- LPWORD lpcPropID,
- CEPROPID* prgPropID,
- LPBYTE lplpBuffer,
- LPDWORD lpcbBuffer,
- HANDLE hHeap
- );
第三个参数是返回属性列的个数,第四个参数即是用来指定要接收哪些属性列的数据,如果为NULL,则接收所有。第五个参数即是返回的数据。如果第二个参数指定为:CEDB_ALLOWREALLOC的话,则在不必要使用lplpBuffer之前申请空间。最后一个参数就是要使用的堆的句柄。
再操作完之后,要使用CloseHandle关闭数据库的句柄,并且再最后CeUnmountDBVol卸载数据库。
EDB数据库的操作
一、WM5以前的系统中一般都是使用的CEDB数据库,EDB是WM5中的新特性之一。为了改善应用程序的性能和长期可移植性,CEDB 已经被 EDB 所取代。EDB 利用了 SQL Mobile 使用的存储子系统,并且提供了明显优于 CEDB 的性能(尤其是在与持久存储区一起使用时)。因为 CEDB 提供了与 EDB 完全相同的函数集 ,所有函数都具有相同的名称和参数列表。但是EDB中也包含了CEDB中所没有函数,并且创建方法也不相同了,要比CEDB复杂。
二、EDB数据库的创建和基本操作
1.创建数据库卷:
- CeMountDBVol( );
- CeCreateDatabaseWithProps();
- CeCreateSession();
- CeOpenDatabaseInSession();
创建EDB时前还要创建一个CEDBASEINFOEX对象,这个对象用于创建EDB中的info,用于设定EDB。
在打开时还要维护一个全局的HANDLE,在以后的操作中是要使用的.
2.对数据库进行读,写,删除的操作
CeSeekDatabaseEx();//定位所要找的数据
CeReadRecordPropsEx();//读出定位的数据
创建一个CEPROPVAL对象,将所要定位数据的条件传给这个结构。
CeWriteRecordProps();//数据写入EDB
创建一个CEPROPVAL对象,或对象数组,将所要写入的数据传给这些对象。
CeSeekDatabaseEx();//定位要删除的数据
CeDeleteRecord();//删除定位的数据
CeWriteRecordProps();//数据写入新数据到EDB覆盖原数据
CloseHandle(打开时的句柄);
3.其他的一些数据库操作函数
列举数据库: CeFindFirstDatabaseEx和CeFindNextDatabase
获得数据库的信息:CeOidGetInfoEx
//在EDB的消息函数中用到
释放通告消息结构体:CeFreeNotification
将数据缓冲到flash上:CeFreeNotification
获得打开的数据库所使用的句柄:CeGetDBInformationByHandle
设置数据库的各种参数:CeSetDatabaseInfoEx
列举所有转载的数据库卷并返回卷名:CeEnumDBVolumes
三、以下是EDB代码示例
- CEOID oid = NULL;
- CEGUID guidVol = {0,};
- BOOL fOK = true;
- HANDLE h = INVALID_HANDLE_VALUE;
- LPWSTR lpwszDBVol = L"volume.db";
- ORTORDERSPECEX s =
- {
- 2,
- 1,
- 0,
- 0,
- 0,
- { 0 }
- };
-
-
- CEDBASEINFOEX info =
- {
- 2,
- 0,
- (CEDB_VALIDNAME | CEDB_VALIDTYPE | CEDB_VALIDSORTSPEC),
- L"Table1",
- 0x777,
- 4,
- NULL,
- {0,},
- };
-
- CEPROPVAL val =
- {
- 0,
- NULL,
- NULL,
- 0
- };
-
- s.rgPropID[0] = CEVT_LPWSTR;
- val.propid = CEVT_LPWSTR;
-
- CEPROPSPEC CEPropSpec[4];
- CEPropSpec[0].wVersion = 1;
- CEPropSpec[0].propid = CEVT_LPWSTR;
- CEPropSpec[0].dwFlags = 0;
- CEPropSpec[0].pwszPropName = TEXT("Name");
- CEPropSpec[0].cchPropName = CEDB_MAXDBASENAMELEN;
-
-
- CEPropSpec[1].wVersion = 1;
- CEPropSpec[1].propid = CEVT_LPWSTR;
- CEPropSpec[1].dwFlags = 0;
- CEPropSpec[1].pwszPropName = TEXT("Phone");
- CEPropSpec[1].cchPropName = CEDB_MAXDBASENAMELEN;
-
-
- CEPropSpec[2].wVersion = 1;
- CEPropSpec[2].propid = CEVT_LPWSTR;
- CEPropSpec[2].dwFlags = 0;
- CEPropSpec[2].pwszPropName = TEXT("Content");
- CEPropSpec[2].cchPropName = CEDB_MAXDBASENAMELEN;
-
-
- CEPropSpec[3].wVersion = 1;
- CEPropSpec[3].propid = CEVT_LPWSTR;
- CEPropSpec[3].dwFlags = 0;
- CEPropSpec[3].pwszPropName = TEXT("Isread");
- CEPropSpec[3].cchPropName = CEDB_MAXDBASENAMELEN;
-
- if (!CeMountDBVolEx(&guidVol, lpwszDBVol, NULL, CREATE_ALWAYS))
- {
- fOK = false;
- goto exit;
- }
-
- if((oid=CeCreateDatabaseWithProps(&guidVol,&info,0,CEPropSpec))==NULL)
- {
- fOK = false;
- goto exit;
- }
-
- if ((h = CeOpenDatabaseInSession(NULL, &guidVol, &oid, NULL, NULL,
- 0, NULL)) == INVALID_HANDLE_VALUE)
- {
- fOK = false;
- goto exit;
- }
-
- CEPROPVAL pProp[4];
- pProp[0].propid = PID_NAME;
- pProp[0].wFlags = 0;
- pProp[0].wLenData = 0;
- pProp[0].val.lpwstr = L"777rewr";
- pProp[1].propid = PID_PHONE;
- pProp[1].wFlags = 0;
- pProp[1].wLenData = 0;
- pProp[1].val.lpwstr = L"888rer";
- pProp[2].propid = PID_CONTENT;
- pProp[2].wFlags = 0;
- pProp[2].wLenData = 0;
- pProp[2].val.lpwstr = L"123rewr";
- pProp[3].propid = PID_ISREADED;
- pProp[3].wFlags = 0;
- pProp[3].wLenData = 0;
- pProp[3].val.lpwstr = L"234rewr";
-
-
- for(int i = 0; i < 100; ++i)
- oid = CeWriteRecordProps(h, 0, 4, pProp);
-
-
- CeWriteRecordProps(h, 0, 4, pProp);
- CeFlushDBVol(&guidVol);
- CloseHandle(h);
- exit:
- CeUnmountDBVol(&guidVol);
查找及删除操作示例:
- bool fOK = true;
- CEOID oid = NULL;
- CEOID oidRow = NULL;
- CEGUID guidVol;
- HANDLE h = INVALID_HANDLE_VALUE;
- HANDLE hDBOpened = NULL;
- CREATE_INVALIDGUID(&guidVol);
-
- if (!CeMountDBVolEx(&guidVol, L"volume.db", NULL, OPEN_EXISTING))
- {
- fOK = false;
- MessageBox(L"Err!!!");
- }
-
-
- if ((h = CeOpenDatabaseInSession(NULL, &guidVol, &oid, L"Table1", NULL,
- CEDB_AUTOINCREMENT, NULL)) == INVALID_HANDLE_VALUE)
- {
- fOK = false;
- MessageBox(L"Err!!!");
- }
-
- CEOIDINFOEX ceoidInfoEx;
- memset(&ceoidInfoEx,0,sizeof(CEOIDINFOEX));
- ceoidInfoEx.wVersion = 2;
-
-
-
-
-
-
-
-
-
-
-
- CeSeekDatabaseEx(h, CEDB_SEEK_BEGINNING, 0, 0, NULL);
-
- WORD dwPropId = 0;
- DWORD dwSizeOfBuffer = 0;
- CEOID ceoidFindRecord = 0;
- WORD wNumRecProps = 0;
- LPBYTE lpRecProps = NULL;
- PCEPROPVAL pCePropVal = NULL;
- DWORD dwBufLen = 256;
- BOOL m_bFlag = FALSE;
- int m_iCount = 0;
-
- while(ceoidFindRecord = CeReadRecordPropsEx(h,
- CEDB_ALLOWREALLOC, &dwPropId, NULL, &lpRecProps, &dwSizeOfBuffer, NULL))
- {
- if(GetLastError() != ERROR_NO_MORE_ITEMS)
- {
- pCePropVal = (PCEPROPVAL)lpRecProps;
- LPWSTR lpnum;
- if (m_iCount%2)
- lpnum = pCePropVal[3].val.lpwstr;
- else
- lpnum = pCePropVal[1].val.lpwstr;
-
- TRACE(L"%d=%s\n",m_iCount,lpnum);
-
- ++m_iCount;
- if(!lpnum )
- {
- CeDeleteRecord(h, ceoidFindRecord);
- m_bFlag = FALSE;
- }
- else
- m_bFlag = TRUE;
- }
- }
-
- CString str;
- str.Format(L"%d",m_iCount);
- MessageBox(str);
-
- if (h)
- CloseHandle(h);
-
- if(&guidVol)
- {
- CeFlushDBVol(&guidVol);
- CeUnmountDBVol(&guidVol);
- }
头文件:
- extern "C"
- {
- #include <windbase_edb.h>
- }
- #define EDB
Windows mobile 5.0系统中操纵EDB
WM5以前的系统中一般都是使用的CEDB数据库,EDB是WM5中的新特性之一。为了改善应用程序的性能和长期可移植性,CEDB 已经被 EDB 所取代。EDB 利用了 SQL Mobile 使用的存储子系统,并且提供了明显优于 CEDB 的性能(尤其是在与持久存储区一起使用时)。因为 CEDB 提供了与 EDB 完全相同的函数集 ,所有函数都具有相同的名称和参数列表。但是EDB中也包含了CEDB中所没有函数,并且创建方法也不相同了,要比CEDB复杂。以下就是EDB的创建和使用法:
一。创建:
1。CeMountDBVol( );//创建卷
2。CeCreateDatabaseWithProps();//卷创建成功后创建EDB
3。CeCreateSession();//EDB创建成功后创建session,用于打开EDB
4。CeOpenDatabaseInSession();//打开EDB
创建EDB时前还要创建一个CEDBASEINFOEX对象,这个对象用于创建EDB中的info,用于设定EDB。
在打开时还要维护一个全局的HANDLE,在以后的操作中是要使用的
二。选择数据
1。CeSeekDatabaseEx();//定位所要找的数据
2。CeReadRecordPropsEx();//读出定位的数据
创建一个CEPROPVAL对象,将所要定位数据的条件传给这个结构。
三。插入数据
CeWriteRecordProps();//数据写入EDB
创建一个CEPROPVAL对象,或对象数组,将所要写入的数据传给这些对象。
四。删除数据
1。CeSeekDatabaseEx();//定位要删除的数据
2。CeDeleteRecord();//删除定位的数据
五。更新数据
所插入数据基本相同,就是将已有数据覆盖
1。CeSeekDatabaseEx();//定位所要找的数据
2。CeWriteRecordProps();//数据写入新数据到EDB覆盖原数据
六。关闭EDB
CloseHandle(打开时的句柄);
在这里关键是创建EDB时所选的参数,和对结构体的使用,这样才能正确定位数据,否则选择、更新、删除都无法实现。
from:http://blog.csdn.net/sc_valentine21/archive/2008/11/07/3245904.aspx
(sc_valentine21) |