INF: How to Use Connectable Objects in SQL-DMO

Last reviewed: April 9, 1997
Article ID: Q156434
The information in this article applies to:
  • Microsoft SQL Server, version 6.5

SUMMARY

The ConnectionPoint event establishes a two-way dialogue between an object and a client, and it allows you to write Component Object Model (COM) objects that are notified by OLE objects when certain events occur. SQL Server 6.5 includes several new and enhanced objects and events for SQL Distributed Management Objects (DMO). Four of the objects (SQLServer, Backup, Transfer, and BulkCopy) now support the ConnectionPoint event. This article demonstrates the usage of SQL-DMO object Backup and BackupSink objects in C++.

MORE INFORMATION

  1. Declare and implement a Sink Object that supports the ISQLOLEBackupSink and IUNKnown interfaces.

class CMyBackupSink : public ISQLOLEBackupSink {
        public:
                CMyBackupSink(){m_cRefs=0;};

//*** IUnknown methods
STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID *ppvObj);
STDMETHOD_(ULONG,AddRef) (THIS)     {return ++m_cRefs;}
STDMETHOD_(ULONG,Release) (THIS)
         {
                  if (1 >= m_cRefs) {
                              //delete this;
                              return 0;
                  }
                return --m_cRefs;
         }
//*** ISQLOLEBackupSink methods
STDMETHOD(DumpComplete) (THIS_ SQLOLE_LPCSTR strDumpComplete);
         STDMETHOD(PercentComplete)(THIS_ SQLOLE_LPCSTR szMessage, long
lPercent); STDMETHOD(NextVolume)(THIS_ SQLOLE_LPCSTR strNextVolume);

        protected:                              //member vars.
                ULONG                           m_cRefs;

};

  • Ask the Connectable Object (pSQLBackup) about its outgoing interface, by using QueryInterface on IID_IConnectionPointContainer. If this fails, this object does not support the outgoing interface.

    LPCONNECTIONPOINTCONTAINER pMyConnectionPointContainer; pSQLBackup->QueryInterface(IID_IConnectionPointContainer,( LPVOID FAR*) &pMyConnectionPointContainer);

  • Find the specific outgoing interface IID_ISQLOLEBackupSink, and retrieve a pointer to the ConnectionPoint Object. If this fails, the object does not support this outgoing interface.

    LPCONNECTIONPOINT pMyConnectionPoint; pMyConnectionPointContainer->FindConnectionPoint(IID_ISQLOLEBackupSink, (LPCONNECTIONPOINT FAR*) &pMyConnectionPoint);

  • Establish the connection between the Sink and ConnectionPoint Object. Retreive a key (cookie) value for terminating the connection later. If this fails, the Sink and ConnectionPoint Object do not support the same interface.

    pMyConnectionPoint->Advise((LPUNKNOWN)pMyBackupSink, &dwCookie));

  • Use the Connectable Object (Backup) as usual. The object will invoke methods supported by the connected outgoing interface when they are appropriate (in this example, the Backup Object calls PercentComplete() as a backup progress, NextVolume() when it needs to send a 'mount next volume' message, and DumpComplete() when the backup completes).

    pSQLDatabase->Dump(pSQLBackup);

  • Terminate the connection using the same connection key.

    pMyConnectionPoint->Unadvise(dwCookie);

    The following is a complete code list on how to monitor the backup process with SQL-DMO, using the Backup and BackupSink objects. For more information about Connectable Objects and the ConnectionPoint Event, see "Inside OLE" by Kraig Brockschmidt.

    #define UNICODE
    #define _UNICODE
    #include <windows.h>
    #include <initguid.h>
    #include <tchar.h>
    #include <sqloleid.h>
    #include <sqlole.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <olectl.h>
    
    int DisplayError();
    
    class CMyBackupSink : public ISQLOLEBackupSink {
            public:
                    CMyBackupSink(){m_cRefs=0;};
    
    //*** IUnknown methods
    
    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID *ppvObj);
    STDMETHOD_(ULONG,AddRef) (THIS)     {return ++m_cRefs;}
    
    STDMETHOD_(ULONG,Release) (THIS)
             {
                      if (1 >= m_cRefs) {
                                  //delete this;
                                  return 0;
                      }
                      return --m_cRefs;
             }
    //*** ISQLOLEBackupSink methods
    
    STDMETHOD(DumpComplete) (THIS_ SQLOLE_LPCSTR strDumpComplete);
             STDMETHOD(PercentComplete)(THIS_ SQLOLE_LPCSTR szMessage, long
    
    lPercent); STDMETHOD(NextVolume)(THIS_ SQLOLE_LPCSTR strNextVolume);

            protected:                              //member vars.
                    ULONG                           m_cRefs;
    
    };
    
    STDMETHODIMP CMyBackupSink::QueryInterface(REFIID riid, LPVOID FAR* ppvObj) {
            if (riid == IID_IUnknown || riid == IID_ISQLOLEBackupSink) {
                    AddRef();
                    *ppvObj = this;
                    return NOERROR;
            }
            return E_NOINTERFACE;
    }
    //Backup Sink Methords.
    
    STDMETHODIMP CMyBackupSink::DumpComplete(THIS_ SQLOLE_LPCSTR szMessage) {
    //Backup object calls us when backup is completed.
       printf("Backup Completed\n");
    
    return NOERROR; }

    STDMETHODIMP CMyBackupSink::PercentComplete(THIS_ SQLOLE_LPCSTR szMessage, long lPercent) {

     //Backup object calls us with new percent complete.
       printf("%ld%s Completed\n", lPercent,"%");
       return NOERROR;
    
    }

    STDMETHODIMP CMyBackupSink::NextVolume(THIS_ SQLOLE_LPCSTR szMessage) {

    //Backup object calls us when it's ready for next volume.
    
    printf("Next Volume Message: %s \n", szMessage);
             return NOERROR;
    }
    
    int main (void)
    
    {
       HRESULT hr;
       if FAILED(hr = CoInitialize (NULL))
       {
          _tprintf(TEXT("CoInitialize Failed\n"));
          return (0);
       }
       LPSQLOLESERVER pSQLServer = NULL;
       if FAILED(hr = CoCreateInstance(CLSID_SQLOLEServer, NULL,
    
    CLSCTX_INPROC_SERVER,
          IID_ISQLOLEServer, (LPVOID*)&pSQLServer))
       {
          _tprintf(TEXT("CoCreateInstance Failed\n"));
          return (0);
       }
       pSQLServer->SetLoginTimeout(10);
       if FAILED(hr = pSQLServer->Connect(TEXT(""),TEXT("sa"),TEXT("")))
          return DisplayError();
    
    LPSQLOLEBACKUP pSQLBackup = NULL; if FAILED(hr = CoCreateInstance(CLSID_SQLOLEBackup, NULL, CLSCTX_INPROC_SERVER,
             IID_ISQLOLEBackup, (LPVOID*)&pSQLBackup))
       {
          _tprintf(TEXT("CoCreateInstance Failed\n"));
          return (0);
       }
       LPCONNECTIONPOINTCONTAINER pMyConnectionPointContainer;
       LPCONNECTIONPOINT pMyConnectionPoint;
             CMyBackupSink* pMyBackupSink = new CMyBackupSink();
       pMyBackupSink->AddRef();
       if(!pMyBackupSink)return(0);
       DWORD dwCookie;
    
    if FAILED(pSQLBackup->QueryInterface(IID_IConnectionPointContainer,( LPVOID FAR*) &pMyConnectionPointContainer))
          return DisplayError();
    
    if FAILED(pMyConnectionPointContainer- >FindConnectionPoint(IID_ISQLOLEBackupSink, (LPCONNECTIONPOINT FAR*) &pMyConnectionPoint))
          return DisplayError();
       if (S_OK!=(hr=pMyConnectionPoint->Advise((LPUNKNOWN)pMyBackupSink,
    
    &dwCookie)))
          return DisplayError();
       if FAILED(hr=pSQLBackup-
    
    >SetDiskDevices(TEXT("'\\\\ocean11\\public\\test.txt'") ))
       return DisplayError();
    
    LPSQLOLEDATABASE pSQLDatabase = NULL;
       if FAILED(pSQLServer->GetDatabaseByName(TEXT("pubs"),&pSQLDatabase))
          return DisplayError();
       printf("Backup Start\n");
       if FAILED(hr=pSQLDatabase->Dump(pSQLBackup))
          return DisplayError();
       pMyConnectionPoint->Unadvise(dwCookie);
       pMyConnectionPoint->Release ();
       pMyConnectionPointContainer->Release ();
       pSQLBackup->Release ();
    
    pSQLServer->Release ();

    CoUninitialize ();

       return (0);
    
    }

    int DisplayError()
    
    {
       LPERRORINFO pErrorInfo=NULL;
       GetErrorInfo(0,&pErrorInfo);
       BSTR strDescription, strSource;
       pErrorInfo->GetDescription (&strDescription);
       pErrorInfo->GetSource(&strSource);
       _tprintf(TEXT("%s\n"),strDescription);
       _tprintf(TEXT("%s\n"),strSource);
       pErrorInfo->Release();
       SysFreeString(strDescription);
       SysFreeString(strSource);
    
    return 0; }


  • Additional query words:
    Keywords : kbprg kbusage SSrvDMO SSrvProg
    Version : 6.5
    Platform : WINDOWS
    Issue type : kbhowto


    THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

    Last reviewed: April 9, 1997
    © 1998 Microsoft Corporation. All rights reserved. Terms of Use.