TN054 : appel de DAO directement pendant l'utilisation des classes DAO MFC
Remarque
DAO est utilisé avec les bases de données Access et est pris en charge via Bureau 2013. DAO 3.6 est la version finale, et elle est considérée comme obsolète. L’environnement et les Assistants Visual C++ ne prennent pas en charge DAO (bien que les classes DAO soient incluses et que vous pouvez toujours les utiliser). Microsoft vous recommande d’utiliser des modèles OLE DB ou ODBC et MFC pour de nouveaux projets. Vous devez uniquement utiliser DAO pour gérer les applications existantes.
Lorsque vous utilisez les classes de base de données DAO MFC, il peut y avoir des situations où il est nécessaire d’utiliser DAO directement. En règle générale, cela ne sera pas le cas, mais MFC a fourni des mécanismes d’assistance pour faciliter l’exécution d’appels DAO directs simples lors de la combinaison de l’utilisation des classes MFC avec des appels DAO directs. L’exécution d’appels directs DAO aux méthodes d’un objet DAO géré par MFC ne doit nécessiter que quelques lignes de code. Si vous devez créer et utiliser des objets DAO qui ne sont pas gérés par MFC, vous devrez effectuer un peu plus de travail en appelant Release
réellement l’objet. Cette note technique explique quand vous souhaiterez peut-être appeler DAO directement, ce que les helpers MFC peuvent faire pour vous aider et comment utiliser les interfaces OLE DAO. Enfin, cette note fournit des exemples de fonctions montrant comment appeler DAO directement pour les fonctionnalités de sécurité DAO.
Quand effectuer des appels DAO directs
Les situations les plus courantes pour effectuer des appels DAO directs se produisent lorsque les regroupements doivent être actualisés ou lorsque vous implémentez des fonctionnalités non encapsulées par MFC. La fonctionnalité la plus importante non exposée par MFC est la sécurité. Si vous souhaitez implémenter des fonctionnalités de sécurité, vous devez utiliser directement les objets DAO User(s) et Group(s). Outre la sécurité, il n’existe que quelques autres fonctionnalités DAO non prises en charge par MFC. Il s’agit notamment des fonctionnalités de clonage de jeu d’enregistrements et de réplication de base de données, ainsi que quelques ajouts tardifs à DAO.
Vue d’ensemble de la mise en œuvre de DAO et de MFC
Le wrapping de MFC de DAO facilite l’utilisation de DAO en gérant beaucoup de détails afin que vous n’ayez pas à vous soucier des petites choses. Cela inclut l’initialisation d’OLE, la création et la gestion des objets DAO (en particulier les objets de collection), l’erreur case activée ing et la fourniture d’une interface fortement typée et plus simple (pas de VARIANT ou BSTR
d’arguments). Vous pouvez effectuer des appels DAO directs et toujours tirer parti de ces fonctionnalités. Tout votre code doit être appelé Release
pour tous les objets créés par des appels DAO directs et ne modifie pas les pointeurs d’interface sur lesquels MFC peut s’appuyer en interne. Par exemple, ne modifiez pas le membre m_pDAORecordset d’un objet ouvert CDaoRecordset
, sauf si vous comprenez toutes les ramifications internes. Toutefois, vous pouvez utiliser l’interface m_pDAORecordset pour appeler DAO directement pour obtenir la collection Fields. Dans ce cas, le membre m_pDAORecordset n’est pas modifié. Vous devez simplement appeler Release
l’objet de collection Fields lorsque vous avez terminé l’objet.
Description des assistances pour faciliter les appels DAO
Les assistances fournies pour faciliter l’appel de DAO sont les mêmes assistances que celles utilisées en interne dans les classes de base de données DAO MFC. Ces helpers sont utilisés pour case activée les codes de retour lors d’un appel DAO direct, journalisation de la sortie de débogage, case activée ing pour les erreurs attendues et levée des exceptions appropriées si nécessaire. Il existe deux fonctions d’assistance sous-jacentes et quatre macros qui correspondent à l’un de ces deux assistances. La meilleure explication consisterait simplement à lire le code. Consultez DAO_CHECK, DAO_CHECK_ERROR, DAO_CHECK_MEM et DAO_TRACE dans AFXDAO. H pour voir les macros, et voir AfxDaoCheck et AfxDaoTrace dans DAOCORE. RPC.
Utilisation des interfaces OLE DAO
Les interfaces OLE pour chaque objet de la hiérarchie d’objets DAO sont définies dans le fichier d’en-tête DBDAOINT. H, qui se trouve dans le répertoire \Program Files\Microsoft Visual Studio .NET 2003\VC7\include. Ces interfaces fournissent des méthodes qui vous permettent de manipuler l’ensemble de la hiérarchie DAO.
Pour la plupart des méthodes des interfaces DAO, vous devez manipuler un BSTR
objet (chaîne préfixée de longueur utilisée dans OLE Automation). L’objet BSTR
est généralement encapsulé dans le type de données VARIANT . La classe COleVariant
MFC elle-même hérite du type de données VARIANT . Selon que vous générez votre projet pour ANSI ou Unicode, les interfaces DAO retournent les interfaces ANSI ou Unicode BSTR
. Deux macros, V_BSTR et V_BSTRT, sont utiles pour vous assurer que l’interface DAO obtient le BSTR
type attendu.
V_BSTR extrait le membre bstrVal d’un COleVariant
. Cette macro est généralement utilisée lorsque vous devez passer le contenu d’une COleVariant
méthode d’interface DAO. Le fragment de code suivant montre à la fois les déclarations et l’utilisation réelle pour deux méthodes de l’interface DAOUser qui tirent parti de la macro V_BSTR :
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)));
Notez que l’argument VT_BSTRT
spécifié dans le COleVariant
constructeur ci-dessus garantit qu’il y aura un ANSI BSTR
dans le COleVariant
cas où vous générez une version ANSI de votre application et un Unicode pour une version Unicode BSTR
de votre application. C’est ce que DAO attend.
L’autre macro, V_BSTRT, extrait un membre COleVariant
ANSI ou Unicode bstrVal en fonction du type de build (ANSI ou Unicode). Le code suivant montre comment extraire la BSTR
valeur d’un COleVariant
dans un CString
:
COleVariant varName(_T("MyName"), VT_BSTRT);
CString str = V_BSTRT(&varName);
La macro V_BSTRT, ainsi que d’autres techniques d’ouverture d’autres types stockés dans COleVariant
, est illustrée dans l’exemple DAOVIEW. Plus précisément, cette traduction est effectuée dans la CCrack::strVARIANT
méthode. Cette méthode, si possible, traduit la valeur d’un COleVariant
dans une instance de CString
.
Exemple simple d’un appel direct à DAO
Les situations peuvent survenir lorsqu’il est nécessaire d’actualiser les objets de collection DAO sous-jacents. Normalement, cela ne doit pas être nécessaire, mais il s’agit d’une procédure simple si nécessaire. Un exemple de cas d’actualisation d’une collection peut être nécessaire lors de l’exploitation dans un environnement multiutilisateur avec plusieurs utilisateurs créant de nouveaux tablesdefs. Dans ce cas, votre collection tabledefs peut devenir obsolète. Pour actualiser la collection, vous devez simplement appeler la Refresh
méthode de l’objet de collection particulier et case activée pour les erreurs :
DAO_CHECK(pMyDaoDatabase->m_pDAOTableDefs->Refresh());
Notez que toutes les interfaces objet de collection DAO sont actuellement des détails d’implémentation non documentés des classes de base de données DAO MFC.
Utilisation directe de DAO pour les fonctionnalités de sécurité DAO
Les classes de base de données DAO MFC ne wrappent pas les fonctionnalités de sécurité DAO. Vous devez appeler des méthodes d’interfaces DAO pour utiliser certaines fonctionnalités de sécurité DAO. La fonction suivante définit la base de données système, puis modifie le mot de passe de l’utilisateur. Cette fonction appelle trois autres fonctions, qui sont ensuite définies.
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 effect.
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);
// ...
}
Les quatre exemples suivants montrent comment :
Définissez la base de données DAO système (. Fichier MDW).
Définissez l’utilisateur et le mot de passe par défaut.
Modifiez le mot de passe d’un utilisateur.
Modifiez le mot de passe d’un . Fichier MDB.
Définition de la base de données système
Vous trouverez ci-dessous un exemple de fonction pour définir la base de données système qui sera utilisée par une application. Cette fonction doit être appelée avant d’effectuer d’autres appels 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));
}
Définition de l’utilisateur et du mot de passe par défaut
Pour définir l’utilisateur et le mot de passe par défaut pour une base de données système, utilisez la fonction suivante :
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));
}
Modification du mot de passe d’un utilisateur
Pour modifier le mot de passe d’un utilisateur, utilisez la fonction suivante :
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->getcount(&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();
}
Modification du mot de passe d’un . Fichier MDB
Pour modifier le mot de passe d’un . Fichier MDB, utilisez la fonction suivante :
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();
}