TN054 : Appeler DAO directement en utilisant les Classes DAO MFC

Lorsque vous utilisez les classes DAO MFC de la base de données, il peut y avoir des situations où il est nécessaire d'utiliser DAO directement. Habituellement ce ne sera pas le cas, mais le MFC a fourni certains mécanismes d'assistance afin de faciliter la prise directs appels DAO simples lorsqu'on combine l'utilisation des classes MFC avec appels directs de DAO. Fabrication directe DAO les appels aux méthodes d'un objet DAO MFC-géré devraient exiger seulement quelques lignes de code. Si vous avez besoin créer et utiliser des objets DAO qui ne sont pas gérés par les MFC, vous devrez faire un peu plus de travail en appelant réellement communiqué sur l'objet. Cette note technique explique quand vous pouvez appeler directement les DAO, que les Assistants MFC peuvent faire pour vous aider et comment utiliser les interfaces OLE DAO. Enfin, la présente note donne quelques exemples de fonctions montrant comment appeler DAO directement pour les fonctionnalités de sécurité DAO.

Quand effectuer des appels directs DAO

Les situations les plus courantes permettant de diriger les appels DAO se produisent lorsque les collections doivent être actualisés ou lorsque vous implémentez caractéristiques ne pas emballés par les MFC. La caractéristique la plus importante ne pas exposée par MFC est sécurité. Si vous souhaitez mettre en place des dispositifs de sécurité, vous devrez utiliser les objets DAO utilisateur et de groupe (s) directement. Outre la sécurité, il y a seulement quelques autres DAO fonctionnalités non pris en charge par les MFC. Ceux-ci comprennent les caractéristiques de jeu d'enregistrements clonage et de la base de données de réplication, ainsi que quelques ajouts fin de DAO.

Un bref aperçu du DAO et de la mise en œuvre du MFC

Habillage de MFC de DAO facilitent utilisant DAO en gérant beaucoup de détails, donc vous n'avez pas à vous soucier de ces petites choses. Il s'agit de l'initialisation de OLE, la création et la gestion des objets DAO (particulièrement les objets de collection), erreur de vérification et en fournissant une interface fortement typé, plus simple (aucun argument de type VARIANT ou BSTR ). Vous pouvez faire des appels directs de DAO et encore tirer parti de ces fonctionnalités. Tout ce que votre code doit faire est appeler Release pour tous les objets créés par les appels directs de DAO et pas modifier les pointeurs d'interface MFC peut s'appuyer sur l'intérieur. Par exemple, ne modifiez pas le membre m_pDAORecordset d'un objet CDaoRecordset ouvert à moins que vous comprenez toutes les ramifications internes. Vous pouvez, toutefois, utiliser l'interface m_pDAORecordset pour appeler DAO directement pour obtenir la collection de champs. Dans ce cas le membre de la m_pDAORecordset ne serait pas modifié. Vous n'avez qu'à appeler Release sur l'objet de collection de champs, lorsque vous avez terminé avec l'objet.

Description des aides pour faire DAO appelle plus facile

Les aides fournies pour faire appeler DAO plus facile sont les mêmes aides qui sont utilisés en interne dans les classes de base de données de DAO MFC. Ces aides sont utilisées pour vérifier les codes de retour lors de la prise d'un appel direct de DAO, journalisation debug output, vérification des erreurs attendues et lancer des exceptions appropriées si nécessaire. Il existe deux fonctions de d'assistance sous-jacent et quatre macros qui correspondent à l'un de ces deux aides. La meilleure explication serait de simplement lire le code. Voir DAO_CHECK, DAO_CHECK_ERROR, DAO_CHECK_MEMet DAO_TRACE en AFXDAO.H à voir les macros et AfxDaoCheck et AfxDaoTrace en DAOCORE.RPC.

En utilisant les Interfaces OLE DAO

Les interfaces OLE pour chaque objet dans la hiérarchie des objets DAO sont définis dans le fichier d'en-tête DBDAOINT.H, qui se trouve dans le répertoire \Program Files\DevStudio\VC\include. Ces interfaces fournissent des méthodes qui vous permettent de manipuler la hiérarchie entière de DAO.

Pour la plupart des méthodes décrites dans les interfaces DAO, vous devrez manipuler un objet BSTR (une chaîne préfixée par sa longueur utilisée dans OLE automation). Généralement, l'objet BSTR est encapsulé dans le type de données VARIANT . La classe MFC COleVariant elle-même hérite du type de données VARIANT . Selon si vous générez votre projet pour ANSI ou Unicode, les interfaces DAO retournera ANSI ou Unicode BSTRs. Deux macros, V_BSTR et V_BSTRT, sont utiles pour garantir que l'interface DAO obtienne le BSTR du type attendu.

V_BSTR extrait le membre bstrVal d'un COleVariant. Cette macro est généralement utilisée lorsque vous devez transmettre le contenu d'un COleVariant à une méthode d'une interface DAO. Le fragment de code suivant montre les déclarations et l'utilisation effective des deux méthodes de l'interface DAO DAOUser qui profitent de la macro V_BSTR:

COleVariant varOldName ;
VarNewName COleVariant (_T("NewUser"), VT_BSTRT) ;

/ / Code pour affecter pUser à une valeur valide omise
DAOUser * pUser = NULL ;

/ / Ces déclarations de méthode ont été tirées du DBDAOINT.H
/ / STDMETHOD(get_Name) (pbstr THIS_ BSTR FAR *) PURE ;
/ / STDMETHOD(put_Name) (THIS_ BSTR bstr) PURE ;

DAO_CHECK (pUser-gt ; get_Name (V_BSTR (& varOldName))) ;
DAO_CHECK (pUser - > put_Name (V_BSTR (& varNewName)))

Notez que l'argument VT_BSTRT spécifié dans le constructeur COleVariant ci-dessus garantit qu'il sera un ANSI BSTR dans le COleVariant si vous générez une version ANSI de votre application et une Uunicode BSTR pour une version Unicode de votre application. C'est ce qui attend les DAO.

La macro V_BSTRT, extrait ANSI ou Unicode bstrVal membre COleVariant selon le type de build (ANSI ou Unicode). Le code suivant montre comment extraire la valeur BSTR un COleVariant dans une CString:

V&arName COleVariant (_T ("MonNom"), VT_BSTRT) ;
CString str = V_BSTRT (amp ; varName)

La macro V_BSTRT , avec les autres astuces pour casser ouvert autre types stockés dans COleVariant, est démontré dans l'exemple DAOVIEW inclus sur le CD-ROM Visual C++. Plus précisément, cette traduction est effectuée dans la méthode CCrack::strVARIANT . Cette méthode, si possible, traduit la valeur d'un COleVariant en une instance de CString.

Exemple simple d'un appel Direct à DAO

Certaines situations peuvent se produire lorsqu'il est nécessaire d'actualiser les objets de collection DAO sous-jacente. Normalement cela ne devrait pas être nécessaire, mais c'est une procédure simple, si c'est nécessaire. Un exemple de quand une collection pourrait besoin d'être rafraîchie est lors d'une exploitation dans un environnement multi-utilisateurs avec plusieurs utilisateurs de créer de nouveaux objets tabledef. Dans ce cas votre collection tabledefs peut-être devenir obsolète. Pour actualiser la collection, il suffit d'appeler la méthode Refresh de la collection particulière d'objets et de vérifier les erreurs:

DAO_CHECK (pMyDaoDatabase-gt ;
    m_pDAOTableDefs - > Actualiser ())

Notez que toutes les interfaces d'objet DAO collection sont, actuellement, détails de mise en œuvre sans papiers des classes de base de données DAO MFC.

À l'aide de DAO directement pour les fonctionnalités de sécurité DAO

Les classes de base de données DAO MFC n'enroulez pas les fonctionnalités de sécurité DAO. Vous devez appeler les méthodes des interfaces DAO pour utiliser certaines fonctionnalités de sécurité DAO. La fonction suivante définit la base de données système et modifie ensuite le mot de passe de l'utilisateur. Cette fonction appelle trois autres fonctions, qui sont définies par la suite.

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 );

   .
   .
   .

}

Les quatre exemples montrent comment:

Définition de la base de données système

Voici un exemple de fonction pour définir la base de données du système qui sera utilisé par une application. Cette fonction doit être appelée avant tous les autres appels DAO.

/ / Définir la base de données système que la / / moteur de base de données DAO utilise

VOID SetSystemDB (CString amp ; strSystemMDB)
{
   VarSystemDB COleVariant (strSystemMDB, VT_BSTRT) ;

/ / Initialiser DAO pour MFC
   AfxDaoInit () ;
   DAODBEngine * pDBEngine = AfxDaoGetEngine () ;

ASSERT (pDBEngine! = NULL) ;

/ / Appelle la méthode put_SystemDB pour définir le / / système de base de données de moteur DAO
   DAO_CHECK (pDBEngine - > put_SystemDB (varSystemDB.bstrVal)) ;
}

Définition de l'utilisateur par défaut et le mot de passe

Pour définir l'utilisateur par défaut et le mot de passe pour une base de données système, utilisez la fonction suivante:

vOID SetDefaultUser (CString amp ; strUserName, CString & strPassword)
{
  VarUserName COleVariant (strUserName, VT_BSTRT) ;
  VarPassword COleVariant (strPassword, VT_BSTRT) ;

DAODBEngine * pDBEngine = AfxDaoGetEngine () ;
  ASSERT (pDBEngine! = NULL) ;

/ / Set d'utilisateur par défaut :
  DAO_CHECK (pDBEngine - > put_DefaultUser (varUserName.bstrVal)) ;

/ / Définir le mot de passe par défaut :
  DAO_CHECK (pDBEngine - > put_DefaultPassword (varPassword.bstrVal)) ;
}

Changer le mot de passe de l'utilisateur

Pour modifier le mot de passe de l'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->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( );
}

Changer le mot de passe d'un.Fichier MDB

Pour modifier le mot de passe d'un.MDB fichier, utilisez la fonction suivante:

vOID SetDBPassword (LPCTSTR pDB, LPCTSTR pszOldPassword, LPCTSTR pszNewPassword)
{
 nbsp ; CDaoDatabase db ;
   StrConnect de CString (_T ("; pwd =")) ;

/ / la base de données doit être ouvert comme exclusive
   / / définir un mot de passe
   DB.Ouvrir (APB, 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() ;
}

&Notes techniques par le numéro |nbsp ; Notes techniques par catégorie

Index