TN054: wywoływanie obiektów DAO bezpośrednio podczas używania klas MFC DAO
[!UWAGA]
Począwszy od programu Visual C++ .NET środowiska Visual C++ i kreatorów już obsługiwać DAO (choć znajdują się klasy DAO i nadal można używać).Firma Microsoft zaleca użycie Szablonów OLE DB lub ODBC i MFC dla nowych projektów.W utrzymaniu istniejących aplikacji należy używać tylko obiektów DAO.
Podczas korzystania z klasami baz danych MFC DAO, może to być sytuacje, gdzie to jest bezpośrednio należy używać obiektów DAO.Zwykle nie będzie to przypadek, ale MFC dostarczył niektórych mechanizmów pomocnika w celu ułatwienia podejmowania bezpośrednich połączeń DAO proste, gdy połączenie użycia klas MFC z bezpośrednich połączeń DAO.Dokonywanie DAO bezpośredniego wywołania metod obiektu DAO zarządzane MFC powinny wymagać tylko kilka wierszy kodu.Jeśli trzeba utworzyć i używać obiektów DAO, które są nie zarządza MFC, trzeba będzie zrobić nieco więcej pracy faktycznie wywołując wersji na obiekcie.Ta uwaga techniczna wyjaśnia, kiedy można bezpośrednio wywołać DAO, co pomocników MFC można zrobić, aby pomóc i jak używać interfejsów DAO OLE.W końcu ta notatka zawiera niektóre funkcje próbki prezentujący wezwać DAO bezpośrednio do funkcji zabezpieczeń obiektów DAO.
Kiedy należy wykonywać połączenia bezpośredniego DAO
Najczęściej występujące sytuacje dokonywania kierowania wywołań obiektów DAO występują, gdy kolekcje wymagają odświeżenia lub kiedy są implementowania funkcji nie zawijać za MFC.Najbardziej znaczący funkcji nie udostępniane przez MFC jest bezpieczeństwo.Jeśli chcesz wdrożyć funkcje zabezpieczeń, musisz bezpośrednio używać obiektów DAO użytkowników i grup.Oprócz zabezpieczeń istnieje tylko kilka innych obiektów DAO funkcji nieobsługiwanych przez MFC.Należą do nich funkcje replikacji rekordów klonowanie i bazy danych, a także kilka dodatków opóźnione do obiektów DAO.
Krótkie omówienie implementacji obiektów DAO i MFC
Zawijanie MFC sprawia, że DAO przy użyciu obiektów DAO łatwiejsze poprzez obsługę wiele informacji, dzięki czemu nie trzeba martwić się o małe rzeczy.Obejmuje to inicjowania OLE, tworzenie i zarządzanie obiektami DAO (zwłaszcza obiekty collection), błąd sprawdzania i zapewnienie jednoznacznie, prostszy interfejs (nie WARIANTU lub BSTR argumenty).Można nawiązywać bezpośrednich połączeń telefonicznych DAO i nadal korzystać z tych funkcji.Wszystko, co musi zrobić kodu jest wywołanie wersji dla obiektów utworzonych przez bezpośrednie DAO wywołuje i nie modyfikować każdy ze wskaźników interfejsu, które MFC może polegać na wewnętrznie.Na przykład, nie należy modyfikować m_pDAORecordset członkiem otwarty CDaoRecordset obiektu bez zrozumienia Wszystkie wewnętrznego konsekwencje.Można jednak użyć m_pDAORecordset interfejs do wywołania DAO bezpośrednio, aby uzyskać kolekcji Fields.W tym przypadku m_pDAORecordset członek nie będzie zmodyfikowany.Po prostu trzeba zadzwonić do wersji w obiekcie kolekcji pól po zakończeniu z obiektem.
Opis pomocników aby DAO wywołuje łatwiejsze
Pomocników dostarczone do wywoływania DAO łatwiejsze są samego wątków, które są używane wewnętrznie do klas MFC DAO w bazie danych.Te są używane do sprawdzania kody powrotne, podczas nawiązywania połączenia bezpośredniego DAO, rejestrowanie wyjścia debugowania, sprawdzanie błędów oczekiwane i generowania wyjątków odpowiednie, jeśli to konieczne.Istnieją dwie podstawowe funkcje pomocnika i cztery makr, które są mapowane do jednego z tych dwóch pomocników.Najlepsze wyjaśnienie będzie po prostu czytać kod.Zobacz DAO_CHECK, DAO_CHECK_ERROR, DAO_CHECK_MEM, i DAO_TRACE w AFXDAO.H-Zobacz makra i AfxDaoCheck i AfxDaoTrace w DAOCORE.CPP.
Za pomocą interfejsów OLE DAO
Interfejsy OLE dla każdego obiektu w hierarchii obiektów DAO, są zdefiniowane w pliku nagłówka DBDAOINT.H, który znajduje się w katalogu \Program Files\Microsoft 2003\VC7\include programu Visual Studio .NET.Interfejsy te zapewniają metody, które umożliwiają manipulowanie całej hierarchii DAO.
Dla wielu metod w interfejsach DAO, trzeba będzie manipulować BSTR obiektu (prefiks długości ciągu używany w automatyzacji OLE).BSTR Obiektu jest zazwyczaj hermetyzowane w WARIANTU typu danych.Klasy MFC COleVariant się dziedziczy z WARIANTU typu danych.W zależności od tego, czy budowania projektu dla ANSI lub Unicode, interfejsy DAO zwróci ANSI lub Unicode BSTRs.Dwóch makr, V_BSTR i V_BSTRT, są używane do zapewnienia, że interfejsu DAO pobiera BSTR oczekiwanego typu.
V_BSTR wyodrębni bstrVal członek COleVariant.To makro jest zazwyczaj używany, gdy trzeba przekazać zawartość COleVariant do metody interfejsu DAO.Poniższy fragment kodu przedstawia deklaracje i rzeczywistego wykorzystania dla dwóch metod interfejsu DAO DAOUser skorzystać z V_BSTR makro:
COleVariant varOldName;
COleVariant varNewName( _T("NewUser"), VT_BSTRT );
// Code to assign pUser to a valid value omitted
DAOUser *pUser = NULL;
// These method declarations were taken from DBDAOINT.H
// STDMETHOD(get_Name) (THIS_ BSTR FAR* pbstr) PURE;
// STDMETHOD(put_Name) (THIS_ BSTR bstr) PURE;
DAO_CHECK( pUser->get_Name( &V_BSTR ( &varOldName ) ));
DAO_CHECK( pUser->put_Name( V_BSTR ( &varNewName ) ));
Należy zauważyć, że VT_BSTRT argument określony w COleVariant Konstruktor powyżej gwarantuje, że będzie ANSI BSTR w COleVariant Jeśli budowanie aplikacji i Unicode wersja ANSI BSTR wersja Unicode dla aplikacji.Jest to, czego oczekuje DAO.
Inne makro, V_BSTRT, rozpakuje ANSI lub Unicode bstrVal członek COleVariant w zależności od typu budowy (ANSI lub Unicode).Poniższy kod ilustruje sposób wyodrębnić BSTR wartość z COleVariant do CString:
COleVariant varName( _T( "MyName" ), VT_BSTRT );
CString str = V_BSTRT( &varName );
V_BSTRT makro, wraz z innymi technikami, aby otworzyć inne typy, które są przechowywane w COleVariant, wykazane w próbce DAOVIEW.W szczególności, tłumaczenie adresów jest wykonywane w CCrack::strVARIANT metody.Ta metoda, jeśli to możliwe, tłumaczy wartości COleVariant do instancji CString.
Prosty przykład bezpośredniego połączenia do obiektów DAO
Mogą powstać sytuacje, gdy należy odświeżyć kolekcji obiektów DAO.Normalnie to nie jest konieczne, ale jest to prosty sposób, jeśli to konieczne.Przykładem kiedy kolekcja może wymagać odświeżenia jest podczas pracy w środowisku wielodostępnym z wieloma użytkownikami tworzenia nowych tabledefs.W tym przypadku kolekcji tabledefs mogą stać się przestarzałe.Aby odświeżyć kolekcji, wystarczy zadzwonić Odśwież metody obiektu kolekcji określonej i wyboru dla błędów:
DAO_CHECK( pMyDaoDatabase->
m_pDAOTableDefs->Refresh( ) );
Należy zauważyć, że obecnie wszystkie interfejsy obiektu kolekcji obiektów DAO szczegóły dotyczące implementacji nieudokumentowanych klasami baz danych MFC DAO.
Bezpośrednio do funkcji zabezpieczeń obiektów DAO przy użyciu obiektów DAO
Klasami baz danych MFC DAO nie jest zawijany funkcje zabezpieczeń obiektów DAO.Należy wywołać metody DAO interfejsów do użycia niektórych funkcji zabezpieczeń obiektów DAO.Poniższa funkcja ustawia systemowej bazy danych, a następnie zmienia hasło użytkownika.Ta funkcja wymaga trzech innych funkcji, które następnie są zdefiniowane.
void ChangeUserPassword( )
{
// Specify path to the Microsoft Access
// system database
CString strSystemDB =
_T( "c:\\Program Files\\MSOffice\\access\\System.mdw" );
// Set system database before MFC initilizes DAO
// NOTE: An MFC module uses only one instance
// of a DAO database engine object. If you have
// called a DAO object in your application prior
// to calling the function below, you must call
// AfxDaoTerm to destroy the existing database
// engine object. Otherwise, the database engine
// object already in use will be reused, and setting
// a system datbase will have no effect.
//
// If you have used a DAO object prior to calling
// this function it is important that DAO be
// terminated with AfxDaoTerm since an MFC
// module only gets one copy of the database engine
// and that engine will be reused if it hasn't been
// terminated. In other words, if you do not call
// AfxDaoTerm and there is currently a database
// initialized, setting the system database will
// have no affect.
SetSystemDB( strSystemDB );
// User name and password manually added
// by using Microsoft Access
CString strUserName = _T( "NewUser" );
CString strOldPassword = _T( "Password" );
CString strNewPassword = _T( "NewPassword" );
// Set default user so that MFC will be able
// to log in by default using the user name and
// password from the system database
SetDefaultUser( strUserName, strOldPassword );
// Change the password. You should be able to
// call this function from anywhere in your
// MFC application
ChangePassword( strUserName, strOldPassword,
strNewPassword );
.
.
.
}
Następne cztery przykłady przedstawiają sposób:
Ustaw systemowej bazy danych DAO (.Plik MDW).
Ustaw domyślny użytkownik i hasło.
Zmienić hasło użytkownika.
Zmienić hasło.Plik MDB.
Ustawienie systemowej bazy danych
Poniżej jest funkcja próbki, aby ustawić systemowej bazy danych, który będzie używany przez aplikację.Ta funkcja musi być wywołana przed wykonaniem jakichkolwiek innych połączeń DAO.
// Set the system database that the
// DAO database engine will use
void SetSystemDB( CString & strSystemMDB )
{
COleVariant varSystemDB( strSystemMDB, VT_BSTRT );
// Initialize DAO for MFC
AfxDaoInit( );
DAODBEngine* pDBEngine = AfxDaoGetEngine( );
ASSERT( pDBEngine != NULL );
// Call put_SystemDB method to set the
// system database for DAO engine
DAO_CHECK( pDBEngine->put_SystemDB( varSystemDB.bstrVal ) );
}
Ustawianie domyślnego użytkownika i hasło
Aby ustawić domyślnego użytkownika i hasło dla systemowej bazy danych, użyć następujących funkcji:
void SetDefaultUser(CString & strUserName, CString & strPassword)
{
COleVariant varUserName( strUserName, VT_BSTRT );
COleVariant varPassword( strPassword, VT_BSTRT );
DAODBEngine* pDBEngine = AfxDaoGetEngine( );
ASSERT( pDBEngine != NULL );
// Set default user:
DAO_CHECK( pDBEngine->put_DefaultUser( varUserName.bstrVal ) );
// Set default password:
DAO_CHECK( pDBEngine->put_DefaultPassword( varPassword.bstrVal ) );
}
Zmiana hasła użytkownika
Aby zmienić hasło użytkownika, należy użyć następujących funkcji:
void ChangePassword( CString &strUserName,
CString &strOldPassword,
CString &strNewPassword )
{
// Create (open) a workspace
CDaoWorkspace wsp;
CString strWspName = _T( "Temp Workspace" );
wsp.Create( strWspName, strUserName,
strOldPassword );
wsp.Append( );
// Determine how many objects there are
// in the Users collection
short nUserCount;
short nCurrentUser;
DAOUser *pUser = NULL;
DAOUsers *pUsers = NULL;
// Side-effect is implicit OLE AddRef( )
// on DAOUser object:
DAO_CHECK( wsp.m_pDAOWorkspace->get_Users( &pUsers ) );
// Side-effect is implicit OLE AddRef( )
// on DAOUsers object
DAO_CHECK( pUsers->get_Count( &nUserCount ) );
// Traverse through the list of users
// and change password for the userid
// used to create/open the workspace
for( nCurrentUser = 0; nCurrentUser < nUserCount;
nCurrentUser++ )
{
COleVariant varIndex( nCurrentUser, VT_I2 );
COleVariant varName;
// Retrieve information for user nCurrentUser
DAO_CHECK( pUsers->get_Item( varIndex, &pUser ) );
// Retrieve name for user nCurrentUser
DAO_CHECK( pUser->get_Name( &V_BSTR( &varName ) ) );
CString strTemp = V_BSTRT( &varName );
// If there is a match, change the password
if( strTemp == strUserName )
{
COleVariant varOldPwd( strOldPassword,
VT_BSTRT );
COleVariant varNewPwd( strNewPassword,
VT_BSTRT );
DAO_CHECK( pUser->NewPassword( V_BSTR( &varOldPwd ),
V_BSTR( &varNewPwd ) ) );
TRACE( "\t Password is changed\n" );
}
}
// Clean up: decrement the usage count
// on the OLE objects
pUser->Release( );
pUsers->Release( );
wsp.Close( );
}
Zmienianie hasła.Plik MDB
Aby zmienić hasło.MDB plik, należy użyć następujących funkcji:
void SetDBPassword( LPCTSTR pDB, LPCTSTR pszOldPassword, LPCTSTR pszNewPassword )
{
CDaoDatabase db;
CString strConnect( _T( ";pwd=" ) );
// the database must be opened as exclusive
// to set a password
db.Open( pDB, TRUE, FALSE,
strConnect + pszOldPassword );
COleVariant NewPassword( pszNewPassword, VT_BSTRT ),
OldPassword( pszOldPassword, VT_BSTRT );
DAO_CHECK( db.m_pDAODatabase->NewPassword( V_BSTR( &OldPassword ),
V_BSTR( &NewPassword ) ) );
db.Close();
}