65.9K
CodeProject is changing. Read more.
Home

Get DataSource Information from CSession Object

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (2 votes)

Feb 6, 2003

1 min read

viewsIcon

42311

downloadIcon

356

A HowTo on getting DataSource information from CSession object

Introduction

This is an easy one. This article will just save you a few clicks and scrolls reading the MSDN guide.

I have encountered a need to get the filename of the MS Access file opened. My class already has a session object as a member. I thought I could add a setFilename() function. But no! Being the lazy programmer, I don't want to do that to my already-tidy clean class; and doing so will require changing all other classes to pass the filename in the chain. The solution: get the filename from the session object.

This article shows how.

Method

  • There is a rowset member object of a session. From that rowset, get the DataSource interface.
    CComPtr spGetDataSource;
    HRESULT hr = r_session.m_spOpenRowset->QueryInterface(
        IID_IGetDataSource, (void**)&spGetDataSource);
  • Get the DBProperties interface from the DataSource object

    CComPtr spProperties;
    hr = spGetDataSource->GetDataSource(IID_IDBProperties, 
        (IUnknown **)&spProperties);
  • Finally, get the data source property you want. For example, get the filename (DBPROP_DATASOURCENAME):
    CDBPropIDSet set(DBPROPSET_DATASOURCEINFO);
    set.AddPropertyID(DBPROP_DATASOURCENAME);
    DBPROPSET* pPropSet = NULL;
    ULONG ulPropSet = 0;
    hr = spProperties->GetProperties(1, &set, &ulPropSet, &pPropSet);
    if (FAILED(hr))
        return hr;
    
    printf(_T("filename = %s\n"), (_bstr_t)(_variant_t)
        pPropSet->rgProperties[0].vValue);
    

Using the code

The file DataSourceInfo.cpp contains the following function which you can use to retreive any data source information.

HRESULT hr_GetDataSourceInfo(CSession & r_session, DWORD dw_infoCode,  
    _variant_t & r_info)
{
    HRESULT hr = S_OK;
    try
    {
        CComPtr spGetDataSource;
        HRESULT hr = r_session.m_spOpenRowset->QueryInterface(
            IID_IGetDataSource, (void**)&spGetDataSource);

        CComPtr spProperties;
        hr = spGetDataSource->GetDataSource(IID_IDBProperties, 
           (IUnknown **)&spProperties);


        CDBPropIDSet set(DBPROPSET_DATASOURCEINFO);
        set.AddPropertyID(dw_infoCode);
        DBPROPSET* pPropSet = NULL;
        ULONG ulPropSet = 0;
        hr = spProperties->GetProperties(1, &set, &ulPropSet, &pPropSet);
        if (FAILED(hr))
        {
            return hr;
        }

        ATLASSERT(ulPropSet == 1);
        VariantCopy(&r_info, &pPropSet->rgProperties[0].vValue);

        CoTaskMemFree(pPropSet->rgProperties);
        CoTaskMemFree(pPropSet);
    }
    catch (...)
    {
        // quite lonely here... put something
    }

    return hr;
}

You will need to pass the session, the data source information property code and a variant that will receive the information.

A list of the data source information properties can be found at the MSDN site.

Conclusion

Finally, may I say - the codes here were written while I'm cooking my dinner :-). I't may not be perfect, but I hope it helped to illustrate my points.