TN054: Chamar o DAO diretamente ao usar Classes MFC DAO

Ao usar as classes de banco de dados MFC DAO, pode haver situações em que é necessário usar o DAO diretamente. Normalmente não será esse o caso, mas MFC tenha fornecido alguns mecanismos de auxiliar para facilitar fazendo chamadas diretas do DAO simples ao combinar o uso de classes MFC com chamadas diretas do DAO. DAO direto de fazer chamadas para os métodos de um objeto gerenciado MFC DAO devem exigir apenas algumas linhas de código. Se você precisa criar e usar objetos DAO não gerenciados pelo MFC, você terá que fazer um pouco mais de trabalho, realmente chamando Release sobre o objeto. Esta anotação técnica explica quando convém chamar o DAO diretamente, o que os auxiliares MFC podem fazer para ajudá-lo e como usar as interfaces do DAO OLE. Finalmente, esta anotação fornece algumas funções de exemplo mostrando como chamar o DAO diretamente para recursos de segurança do DAO.

Quando fazer chamadas diretas do DAO

As situações mais comuns para fazer direcionar chamadas DAO ocorrem quando coleções precisam ser atualizados ou quando você estiver implementando recursos não envolvidos pelo MFC. O recurso mais significativo não exposto pelo MFC é segurança. Se você quiser implementar recursos de segurança, você precisará usar os objetos DAO user (s) e grupo (s) diretamente. Além de segurança, existem apenas alguns outros DAO recursos não suportados pelo MFC. Estes incluem recursos de replicação de banco de dados e clonagem de conjunto de registros, bem como algumas adições finais para o DAO.

Uma visão geral de DAO e de implementação do MFC

Acondicionamento do MFC de faz DAO usando DAO mais fácil por manipulação muitos dos detalhes para que você não tem que se preocupar com as coisas pequenas. Isso inclui a inicialização de OLE, a criação e o gerenciamento dos objetos DAO (especialmente os objetos da coleção), erro verificar e fornecer uma interface de rigidez, mais simples (sem VARIANT ou BSTR argumentos). Você pode fazer chamadas diretas do DAO e ainda tirar proveito desses recursos. Tudo o que seu código deve fazer é chamar Release para quaisquer objetos criados por chamadas diretas do DAO e não modificar qualquer um dos ponteiros de interface que MFC pode contar com internamente. Por exemplo, não modificar o membro de m_pDAORecordset de um abrir CDaoRecordset objeto a menos que você compreende todas as ramificações internas. Você poderia, no entanto, usar a interface de m_pDAORecordset chamar o DAO diretamente para get a coleção de campos. Neste caso o membro de m_pDAORecordset não poderia ser modificado. Você simplesmente tem que chamar Release sobre o objeto de coleção de campos quando tiver terminado com o objeto.

Descrição de ajudantes para fazer DAO chamadas mais fácil

Os auxiliares fornecidos para fazer a chamada DAO mais fácil são os mesmos auxiliares que são usados internamente nas classes de banco de dados MFC DAO. Esses ajudantes são usadas para verificar os códigos de retorno ao fazer uma chamada direta do DAO, Registrando saída de Depurar, verificando erros esperados e gerar exceções apropriadas se necessário. Existem duas funções de auxiliar subjacente e quatro macros que mapeiam para um destes dois ajudantes. A melhor explicação seria simplesmente ler o código. Consulte DAO_CHECK, DAO_CHECK_ERROR, DAO_CHECK_MEMe DAO_TRACE em AFXDAO.H para ver as macros e consulte AfxDaoCheck e AfxDaoTrace em DAOCORE.CPP.

Usando as Interfaces do DAO OLE

As interfaces OLE para cada objeto na hierarquia de objetos DAO são definidas no arquivo de cabeçalho DBDAOINT.H, que é encontrado no diretório \Program Files\DevStudio\VC\include. Essas interfaces fornecem métodos que permitem que você manipule toda a hierarquia DAO.

Para muitos dos métodos nas interfaces do DAO, você precisará manipular um objeto BSTR (uma length-prefixed cadeia usada na automação OLE). O objeto BSTR normalmente é encapsulado dentro do tipo de dados VARIANT . A classe do MFC COleVariant próprio herda o tipo de dados VARIANT . Dependendo se você Compilação seu projeto para ANSI ou Unicode, as interfaces do DAO retornará s BSTRANSI ou Unicode. Duas macros, V_BSTR e V_BSTRT, são úteis para garantir que a interface do DAO Obtém o BSTR do tipo esperado.

V_BSTR extrairá o membro bstrVal um COleVariant. Essa macro normalmente é usada quando você precisar passar o conteúdo de um COleVariant para um método de uma interface do DAO. O fragmento de código a seguir mostra as declarações e o uso real para dois métodos da interface DAOUser DAO que aproveitam a macro V_BSTR:

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

/ / Código para atribuir pUser para um valor válido omitido
DAOUser * pUser = NULL;

/ / Essas declarações de método foram tiradas de DBDAOINT.H
/ / STDMETHOD(get_Name) (extremo de BSTR THIS_ * pbstr) pura;
/ / STDMETHOD(put_Name) (THIS_ BSTR bstr) pura;

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

Observe que o argumento VT_BSTRT especificado no Construtor COleVariant acima garante que lá será um ANSI BSTR no COleVariant se você ComCompilação uma versão ANSI do seu aplicativo e um Uunicode BSTR para uma versão de Unicode do seu aplicativo. Isso é o que espera DAO.

A macro, V_BSTRT, irá extrair um ANSI ou Unicode bstrVal membro COleVariant dependendo do tipo de compilação (ANSI ou Unicode). O código a seguir demonstra como extrair o valor BSTR um COleVariant em um CString:

COleV&ariant varName ( t ("MyName"), VT_BSTRT);
CString str = V_BSTRT (amp; varName)

A macro V_BSTRT , juntamente com outros truques para rachar aberto outro tipos armazenados dentro de COleVariant, é demonstrado no exemplo DAOVIEW incluído no CD do Visual C++. Especificamente, esta tradução é feita no método CCrack::strVARIANT . Este método, sempre que possível, converte o valor de um COleVariant em uma instância de CString.

Exemplo simples de uma chamada direta para o DAO

Situações podem surgir quando é necessário atualizar os objetos de coleção DAO subjacentes. Normalmente isto não deve ser necessário, mas é um procedimento simples se for necessário. Um exemplo de quando uma coleção talvez precise ser atualizado é quando operando em um ambiente multiusuário com Múltiplo usuários criando novos tabledefs. Neste caso sua coleção tabledefs pode se tornar obsoleta. Para atualizar a coleção, basta chamar o método Refresh do objeto de coleção particular e verificar se há erros:

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

Note que atualmente todas as interfaces de objeto de coleção DAO são detalhes de implementação não documentado das classes de banco de dados MFC DAO.

Usando o DAO diretamente para recursos de segurança do DAO

As classes de banco de dados DAO MFC não encapsular recursos de segurança do DAO. Você deve chamar métodos de interfaces do DAO para usar alguns recursos de segurança do DAO. A função a seguir define o banco de dados do sistema e, em seguida, altera a senha do usuário. Esta função chama três outras funções, que são posteriormente definidas.

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

   .
   .
   .

}

O Avançar quatro exemplos demonstrar como:

Definindo o banco de dados do sistema

Abaixo está um exemplo de função para definir o banco de dados do sistema que será usado por um aplicativo. Esta função deve ser chamado antes de quaisquer outras chamadas DAO são feitas.

/ / Definir o banco de dados do sistema que o / / usará o mecanismo de banco de dados DAO

privatevoid SetSystemDB (CString amp; strSystemMDB)
{
   COleVariant varSystemDB (strSystemMDB, VT_BSTRT);

/ / Inicializar o DAO MFC
   AfxDaoInit ();
   DAODBEngine * pDBEngine = AfxDaoGetEngine ();

ASSERT (pDBEngine! = NULL);

/ / Chame o método put_SystemDB para definir o / / sistema de banco de dados para o mecanismo do DAO
   DAO_CHECK (pDBEngine - > put_SystemDB (varSystemDB.bstrVal));
}

Definir o usuário padrão e senha

Para definir o usuário padrão e senha para um banco de dados do sistema, use a seguinte função:

void SetDefaultUser (CString amp; strUserName, CString & strPassword)
{
  COleVariant varUserName (strUserName, VT_BSTRT);
  COleVariant varPassword (strPassword, VT_BSTRT);

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

/ / Definir o usuário padrão:
  DAO_CHECK (pDBEngine - > put_DefaultUser (varUserName.bstrVal));

/ / Definir senha padrão:
  DAO_CHECK (pDBEngine - > put_DefaultPassword (varPassword.bstrVal));
}

Alterando a senha do usuário

Para alterar uma senha de usuário, use a seguinte função:

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

Alterando a senha de um.Arquivo MDB

Para alterar a senha de um.MDB file, use a seguinte função:

privatevoid SetDBPassword (LPCTSTR pDB, LPCTSTR pszOldPassword, LPCTSTR pszNewPassword)
{
 nbsp; CDaoDatabase db;
   StrConnect CString ( t ("; pwd ="));

/ / banco de dados deve ser aberto como exclusiva
   / / para definir uma palavra-passe
   DB.Abrir (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 ();
}

Técnico anotações por número |nbsp; &Notas técnicas por categoria

Index