MDAC 2.5 SDK - OLE DB Programmer's Reference
Chapter 2: Data Source and Session Objects


 

Data Source Object Example

The code in this example shows how to create and initialize a data source object.

/////////////////////////////////////////////////////////////////
// myCreateDataSource
//
// This function creates an OLE DB data source object for a
// provider selected by the user, sets initialization properties
// for the data source, and initializes the data source. The
// function returns a pointer to the data source object's
// IUnknown in *ppUnkDataSource.
//
/////////////////////////////////////////////////////////////////
HRESULT myCreateDataSource
   (
   IUnknown **            ppUnkDataSource
   )
{
   HRESULT                hr;
   IDataInitialize *      pIDataInitialize         = NULL;
   IDBPromptInitialize *  pIDBPromptInitialize     = NULL;
   IDBInitialize *        pIDBInitialize           = NULL;
   CLSID                  clsid                   = CLSID_MSDASQL;

   // Use the Microsoft Data Links UI to create the data source
   // object; this will allow the user to select the provider
   // to connect to and to set the initialization properties
   // for the data source object, which will be created by the
   // Data Links UI.
   if( g_dwFlags & USE_PROMPTDATASOURCE )
   {
      // Create the Data Links UI object, and obtain the
      // IDBPromptInitialize interface from it.
      XCHECK_HR(hr = CoCreateInstance(
                CLSID_DataLinks,                  // clsid--Data Links UI
                NULL,                             // pUnkOuter
                CLSCTX_INPROC_SERVER,              // dwClsContext
                IID_IDBPromptInitialize,           // riid
                (void**)&pIDBPromptInitialize));   // ppvObj
               
      // Invoke the Data Links UI to allow the user to select
      // the provider and set initialization properties for
      // the data source object that this will create.
      XCHECK_HR(hr = pIDBPromptInitialize->PromptDataSource(
                NULL,                            // pUnkOuter
                GetDesktopWindow(),               // hWndParent
                DBPROMPTOPTIONS_PROPERTYSHEET,    // dwPromptOptions
                0,                               // cSourceTypeFilter
                NULL,                            // rgSourceTypeFilter
                NULL,                            // pwszszzProviderFilter
                IID_IDBInitialize,                // riid
                (IUnknown**)&pIDBInitialize));    // ppDataSource
               
      // We've obtained a data source object from the Data Links UI. This
      // object has had its initialization properties set, so all we
      // need to do is initialize it.
      XCHECK_HR(hr = pIDBInitialize->Initialize());
   }
   // We are not using the Data Links UI to create the data source 
   // object. Instead, we will enumerate the providers installed on this 
   // system through the OLE DB enumerator and will allow the user to 
   // select the ProgID of the provider for which we will create a 
   // data source object.
   else
   {
      // Use the OLE DB enumerator to obtain a rowset of installed ,
      // providers, and then allow the user to select a provider from 
      // this rowset.
      CHECK_HR(hr = myCreateEnumerator(CLSID_OLEDB_ENUMERATOR, &clsid));

      // We will create the data source object through the OLE DB service
      // component IDataInitialize interface, so we need to create an
      // instance of the data initialization object.
      XCHECK_HR(hr = CoCreateInstance(
                CLSID_MSDAINITIALIZE,         // clsid--data initialize
                NULL,                        // pUnkOuter
                CLSCTX_INPROC_SERVER,         // dwClsContext
                IID_IDataInitialize,          // riid
                (void**)&pIDataInitialize));  // ppvObj
               
      // Use IDataInitialize::CreateDBInstance to create an uninitialized
      // data source object for the chosen provider. By using this 
      // service component method, the service component manager can 
      // provide additional functionality beyond what is natively 
      // supported by the provider if the consumer requests that 
      // functionality.
      XCHECK_HR(hr = pIDataInitialize->CreateDBInstance(
                clsid,                           // clsid--provider
                NULL,                            // pUnkOuter
                CLSCTX_INPROC_SERVER,            // dwClsContext
                NULL,                            // pwszReserved
                IID_IDBInitialize,               // riid
                (IUnknown**)&pIDBInitialize));    // ppDataSource
               
      // Initialize the data source object by setting any required
      // initialization properties and calling IDBInitialize::Initialize.
      CHECK_HR(hr = myDoInitialization(pIDBInitialize));
   }

CLEANUP:
   *ppUnkDataSource = pIDBInitialize;
   if( pIDataInitialize )
      pIDataInitialize->Release();
   if( pIDBPromptInitialize )
      pIDBPromptInitialize->Release();
   return hr;
}


/////////////////////////////////////////////////////////////////
// myDoInitialization
//
// This function sets initialization properties that tell the
// provider to prompt the user for any information required to
// initialize the provider, and then calls the provider's 
// initialization function.
//
/////////////////////////////////////////////////////////////////
HRESULT myDoInitialization
   (
   IUnknown *           pIUnknown
   )
{
   HRESULT              hr;
   IDBInitialize *      pIDBInitialize      = NULL;
   IDBProperties *      pIDBProperties      = NULL;
   HWND                 hWnd               = GetDesktopWindow();
   
   const ULONG          cProperties         = 2;
   DBPROP               rgProperties[cProperties];
   DBPROPSET            rgPropSets[1];

   // To initialize the data source object, most providers require
   // some initialization properties to be set by the consumer. For 
   // instance, these might include the data source to connect to and the 
   // user ID and password to use to establish identity. We will ask the 
   // provider to prompt the user for this required information by 
   // setting the following properties:
   myAddProperty(&rgProperties[0],DBPROP_INIT_PROMPT,VT_I2,
                 DBPROMPT_COMPLETE);
   myAddProperty(&rgProperties[1],DBPROP_INIT_HWND,  VT_I4,(LONG)hWnd);

   rgPropSets[0].rgProperties      = rgProperties;
   rgPropSets[0].cProperties      = cProperties;
   rgPropSets[0].guidPropertySet   = DBPROPSET_DBINIT;

   // Obtain the needed interfaces.
   XCHECK_HR(hr = pIUnknown->QueryInterface(IID_IDBProperties, 
             (void**)&pIDBProperties));
   XCHECK_HR(hr = pIUnknown->QueryInterface(IID_IDBInitialize, 
             (void**)&pIDBInitialize));

   // If a provider requires initialization properties, it must support 
   // the properties that we are setting (_PROMPT and _HWND). However, 
   // some providers do not need initialization properties and may 
   // therefore not support the _PROMPT and _HWND properties. Because of 
   // this, we will not check the return value from SetProperties.
   hr = pIDBProperties->SetProperties(1, rgPropSets);

   // Now that we've set our properties, initialize the provider.
   XCHECK_HR(hr = pIDBInitialize->Initialize());

CLEANUP:
   if( pIDBProperties )
      pIDBProperties->Release();
   if( pIDBInitialize )
      pIDBInitialize->Release();
   return hr;
}