OLE DB Programmer's Reference |
The code in this example shows how to get the value of a property and how to add properties to a rowset.
///////////////////////////////////////////////////////////////// // myGetProperty // // This function gets the BOOL value for the specified property // and returns the result in *pbValue. // ///////////////////////////////////////////////////////////////// HRESULT myGetProperty ( IUnknown * pIUnknown, REFIID riid, DBPROPID dwPropertyID, REFGUID guidPropertySet, BOOL * pbValue ) { HRESULT hr; DBPROPID rgPropertyIDs[1]; DBPROPIDSET rgPropertyIDSets[1]; ULONG cPropSets = 0; DBPROPSET * rgPropSets = NULL; IDBProperties * pIDBProperties = NULL; ISessionProperties * pISesProps = NULL; ICommandProperties * pICmdProps = NULL; IRowsetInfo * pIRowsetInfo = NULL; // Initialize the output value. *pbValue = FALSE; // Set up the property ID array. rgPropertyIDs[0] = dwPropertyID; // Set up the Property ID Set. rgPropertyIDSets[0].rgPropertyIDs = rgPropertyIDs; rgPropertyIDSets[0].cPropertyIDs = 1; rgPropertyIDSets[0].guidPropertySet = guidPropertySet; // Get the property value for this property from the provider, but // don't try to display extended error information, since this may // not be a supported property. A failure is, in fact, expected if // the property is not supported. if( riid == IID_IDBProperties ) { XCHECK_HR(hr = pIUnknown->QueryInterface(IID_IDBProperties, (void**)&pIDBProperties)); CHECK_HR(hr = pIDBProperties->GetProperties( 1, // cPropertyIDSets rgPropertyIDSets, // rgPropertyIDSets &cPropSets, // pcPropSets &rgPropSets)); // prgPropSets } else if( riid == IID_ISessionProperties ) { XCHECK_HR(hr = pIUnknown->QueryInterface(IID_ISessionProperties, (void**)&pISesProps)); CHECK_HR(hr = pISesProps->GetProperties( 1, // cPropertyIDSets rgPropertyIDSets, // rgPropertyIDSets &cPropSets, // pcPropSets &rgPropSets)); // prgPropSets } else if( riid == IID_ICommandProperties ) { XCHECK_HR(hr = pIUnknown->QueryInterface(IID_ICommandProperties, (void**)&pICmdProps)); CHECK_HR(hr = pICmdProps->GetProperties( 1, // cPropertyIDSets rgPropertyIDSets, // rgPropertyIDSets &cPropSets, // pcPropSets &rgPropSets)); // prgPropSets } else { XCHECK_HR(hr = pIUnknown->QueryInterface(IID_IRowsetInfo, (void**)&pIRowsetInfo)); CHECK_HR(hr = pIRowsetInfo->GetProperties( 1, // cPropertyIDSets rgPropertyIDSets, // rgPropertyIDSets &cPropSets, // pcPropSets &rgPropSets)); // prgPropSets } // Return the value for this property to the caller if // it's a VT_BOOL type value, as expected. if( V_VT(&rgPropSets[0].rgProperties[0].vValue) == VT_BOOL ) *pbValue = V_BOOL(&rgPropSets[0].rgProperties[0].vValue); CLEANUP: // Notice that in addition to calling IMalloc::Free // for the rgProperties element within each element of // rgPropSets, cleanup code also calls VariantClear for // the vValue property of each DBPROPSET structure in // order to prevent a memory leak in cases where the // variant contains a reference type (such as a BSTR.) ULONG iPropSet; ULONG iProp; Assert((rgPropSets != NULL) || (cPropSets == 0)); if( rgPropSets ) { for(iPropSet = 0; iPropSet < cPropSets; iPropSet++) { Assert((rgPropSets[iPropSet].cProperties == 0) || (rgPropSets[iPropSet].rgProperties != NULL)); if(rgPropSets[iPropSet].rgProperties) { for(iProp = 0; iProp < rgPropSets[iPropSet].cProperties; iProp++) { VariantClear(&(rgPropSets[iPropSet].rgProperties[iProp].vValue)); } Free(rgPropSets[iPropSet].rgProperties); } } Free(rgPropSets); } if( pIDBProperties ) pIDBProperties->Release(); if( pISesProps ) pISesProps->Release(); if( pICmdProps ) pICmdProps->Release(); if( pIRowsetInfo ) pIRowsetInfo->Release(); return hr; } ///////////////////////////////////////////////////////////////// // myAddProperty // // This function initializes the property structure pProp. // ///////////////////////////////////////////////////////////////// void myAddProperty ( DBPROP * pProp, DBPROPID dwPropertyID, VARTYPE vtType, LONG lValue, DBPROPOPTIONS dwOptions ) { // Set up the property structure. pProp->dwPropertyID = dwPropertyID; pProp->dwOptions = dwOptions; pProp->dwStatus = DBPROPSTATUS_OK; pProp->colid = DB_NULLID; V_VT(&pProp->vValue) = vtType; // Since VARIANT data is a union, we can place the value in any // member (except for VT_DECIMAL, which is a union with the whole // VARIANT structure -- but we know we're not passing VT_DECIMAL). V_I4(&pProp->vValue) = lValue; } ///////////////////////////////////////////////////////////////// // myAddRowsetProperties // // This function sets up the given DBPROPSET and DBPROP // structures, adding two optional properties that describe // features that we would like to use on the Rowset created // with these properties applied: // - DBPROP_CANFETCHBACKWARDS -- the rowset should support // fetching rows backwards from our current cursor position. // - DBPROP_IRowsetLocate -- the rowset should support // the IRowsetLocate interface and its semantics. // ///////////////////////////////////////////////////////////////// void myAddRowsetProperties(DBPROPSET* pPropSet, ULONG cProperties, DBPROP* rgProperties) { // Initialize the property set array. pPropSet->rgProperties = rgProperties; pPropSet->cProperties = cProperties; pPropSet->guidPropertySet = DBPROPSET_ROWSET; // Add the following two properties (as OPTIONAL) to the property // array contained in the property set array in order to request // that they be supported by the rowset we will create. Because // these are optional, the rowset we obtain may or may not support // this functionality. We will check for the functionality that // we need once the rowset is created and will modify our behavior // appropriately. myAddProperty(&rgProperties[0], DBPROP_CANFETCHBACKWARDS); myAddProperty(&rgProperties[1], DBPROP_IRowsetLocate); }
1998-2001 Microsoft Corporation. All rights reserved.