Creating a Session
After you initialize the data source object, you must create a session object to manage the session and provide the framework needed to create a rowset with IOpenRowset::OpenRowset. The IDBCreateSession::CreateSession interface on the data source object enables you to create a new session object and returns an interface pointer to the session.
The source code for IDBCreateSession::CreateSession follows; you can find the complete source code for the IDBCreateSession interface in CrtSess.cpp.
// CImpIDBCreateSession::CreateSession ------------------------------------------------
//
// @mfunc Creates a new DB Session object from the DSO, and returns the
// requested interface on the newly created object.
//
// @rdesc HRESULT
// @flag S_OK | The method succeeded.
// @flag E_INVALIDARG | ppDBSession was NULL
// @flag DB_E_NOAGGREGATION | pUnkOuter was not NULL (this object does not support
// being aggregated)
// @flag E_FAIL | Provider-specific error. This provider can only create
// one DBSession
// @flag E_OUTOFMEMORY | Out of memory
// @flag E_NOINTERFACE | Could not obtain requested interface on DBSession object
//
STDMETHODIMP CImpIDBCreateSession::CreateSession
(
IUnknown* pUnkOuter, //@parm IN | Controlling IUnknown if being aggregated
REFIID riid, //@parm IN | The ID of the interface
IUnknown** ppDBSession //@parm OUT | A pointer to memory in which to return the interface pointer
)
{
//
// Asserts
//
assert(m_pObj);
//
// Check in-params and NULL out-params in case of error
//
if( !ppDBSession )
return (E_INVALIDARG);
*ppDBSession = NULL;
//
// Check to see if the DSO is Uninitialized
//
if( !m_pObj->m_fDSOInitialized )
return (E_UNEXPECTED);
//
// This Data Source object can only create 1 DBSession...
//
if( m_pObj->m_fDBSessionCreated )
return (DB_E_OBJECTCREATIONLIMITREACHED);
//
// We do not allow any other iid than IID_IUnknown for aggregation
//
if( pUnkOuter && riid != IID_IUnknown )
return (DB_E_NOAGGREGATION);
//
// Open a DBSession object
//
CDBSession* pDBSession = new CDBSession(pUnkOuter);
if( !pDBSession || !pDBSession->FInit(m_pObj) )
{
SAFE_DELETE(pDBSession);
return (E_OUTOFMEMORY);
}
//
// Get requested interface pointer on DBSession
//
HRESULT hr=pDBSession->QueryInterface(riid, (void **)ppDBSession);
if( FAILED(hr) )
{
SAFE_DELETE(pDBSession);
return (hr);
}
m_pObj->m_fDBSessionCreated = TRUE;
return (hr);
}
Once the session has been created, the provider must expose the interface pointer to the data source object that created the session. This interface pointer is exposed through the mandatory interface IGetDataSource. The code for IGetDataSource::GetDataSource follows; you can find the complete source code for the IGetDataSource interface in DBSess.cpp.
//-----------------------------------------------------------------------------
// CImpIGetDataSource::GetDataSource
//
// @mfunc Retrieve an interface pointer on the session object
//
// @rdesc
// @flag S_OK | Session Object Interface returned
// @flag E_INVALIDARG | ppDataSource was NULL
// @flag E_NOINTERFACE | IID not supported
//
STDMETHODIMP CImpIGetDataSource::GetDataSource
(
REFIID riid, // @parm IN | IID desired
IUnknown** ppDataSource // @parm OUT | ptr to interface
)
{
//
// Asserts
//
assert(m_pObj);
assert(m_pObj->m_pCDataSource);
assert(m_pObj->m_pCDataSource->m_pUnkOuter);
//
// Check in-params and NULL out-params in case of error
//
if( !ppDataSource )
return (E_INVALIDARG);
//
// Handle Aggregated DataSource (if aggregated)
//
return m_pObj->m_pCDataSource->m_pUnkOuter->QueryInterface(riid, (LPVOID*)ppDataSource);
}
// ISessionProperties::GetProperties ----------------------------------------------------
//
// @mfunc Returns current settings of all properties in the DBPROPFLAGS_SESSION property
// group
// @rdesc HRESULT
// @flag S_OK | The method succeeded
// @flag E_INVALIDARG | pcProperties or prgPropertyInfo was NULL
// @flag E_OUTOFMEMORY | Out of memory
//
STDMETHODIMP CImpISessionProperties::GetProperties
(
ULONG cPropertySets, //@parm IN | count of restiction guids
const DBPROPIDSET rgPropertySets[], //@parm IN | restriction guids
ULONG* pcProperties, //@parm OUT | count of properties returned
DBPROPSET** prgProperties //@parm OUT | property information returned
)
{
HRESULT hr;
//
// Asserts
//
assert(m_pObj);
assert(m_pObj->m_pUtilProp);
//
// Check in-params and NULL out-params in case of error
//
hr = m_pObj->m_pUtilProp->GetPropertiesArgChk(PROPSET_SESSION,
cPropertySets, rgPropertySets, pcProperties, prgProperties);
if( FAILED(hr) )
return hr;
//
// Just pass this call on to the utility object that manages our properties
//
return m_pObj->m_pUtilProp->GetProperties(PROPSET_SESSION, cPropertySets,
rgPropertySets, pcProperties, prgProperties);
}