//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1994 - 2000. // // File: proprst.cxx // // Contents: This object handles rowset/command properties // // Classes: CMRowsetProps : public CUtlProps // // History: 10-28-97 danleg Created // //---------------------------------------------------------------------------- #include #pragma hdrstop #define DBINITCONSTANTS #include #undef DBINITCONSTANTS #include #include #include #include #include "propinfr.h" #include "proptbl.hxx" // // Constants // static const LCID InvalidLCID = 0xFFFFFFFF; // // This array describes all the known rowset properties // const SPropDescription CMRowsetProps::aPropDescriptions[] = { { DBPROP_ABORTPRESERVE, FALSE, eNotSupported, -1 }, { DBPROP_APPENDONLY, FALSE, eNotSupported, -1 }, { DBPROP_BLOCKINGSTORAGEOBJECTS, FALSE, eDefaultFalse, -1 }, { DBPROP_BOOKMARKS, TRUE, eLocatable, eid_PROPVAL_BOOKMARKS }, { DBPROP_BOOKMARKSKIPPED, FALSE, eDefaultFalse, -1 }, { DBPROP_BOOKMARKTYPE, FALSE, eNumeric, -1 }, { DBPROP_CACHEDEFERRED, FALSE, eColumnProp, -1 }, { DBPROP_CANFETCHBACKWARDS, FALSE, eLocatable, -1 }, { DBPROP_CANHOLDROWS, TRUE, eHoldRows, eid_PROPVAL_CANHOLDROWS }, { DBPROP_CANSCROLLBACKWARDS, FALSE, eLocatable, -1 }, { DBPROP_CHANGEINSERTEDROWS, FALSE, eNotSupported, -1 }, { DBPROP_COLUMNRESTRICT, FALSE, eDefaultFalse, -1 }, // { DBPROP_CHAPTERED, FALSE, eChaptered, -1 }, { DBPROP_COMMANDTIMEOUT, TRUE, eNumeric, eid_PROPVAL_COMMANDTIMEOUT }, { DBPROP_COMMITPRESERVE, FALSE, eNotSupported, -1 }, { DBPROP_DEFERRED, FALSE, eColumnProp, -1 }, { DBPROP_DELAYSTORAGEOBJECTS, FALSE, eNotSupported, -1 }, { DBPROP_IMMOBILEROWS, FALSE, eNotSupported, -1 }, { DBPROP_LITERALBOOKMARKS, FALSE, eDefaultFalse, -1 }, { DBPROP_LITERALIDENTITY, FALSE, eLocatable, -1 }, { DBPROP_MAXOPENROWS, FALSE, eNumeric, -1 }, { DBPROP_MAXPENDINGROWS, FALSE, eNotSupported, -1 }, { DBPROP_MAXROWS, TRUE, eNumeric, eid_PROPVAL_MAXROWS }, { DBPROP_FIRSTROWS, TRUE, eFirstRows, eid_PROPVAL_FIRSTROWS }, { DBPROP_MAYWRITECOLUMN, FALSE, eColumnProp, -1 }, { DBPROP_MEMORYUSAGE, TRUE, eNumeric, eid_PROPVAL_MEMORYUSAGE }, // { DBPROP_MULTICHAPTERED, FALSE, eChaptered, -1 }, // { DBPROP_MULTIPLEACCESSORS, FALSE, eDefaultTrue, -1 }, // { DBPROP_MULTIPLERESULTSETS, FALSE, eNotSupported, -1 }, // { DBPROP_NOTIFICATIONGRANULARITY, FALSE, eNumeric, -1 }, { DBPROP_NOTIFICATIONPHASES, FALSE, eNumeric, -1 }, { DBPROP_NOTIFYROWSETRELEASE, FALSE, eNumeric, -1 }, { DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE,FALSE, eNumeric, -1 }, // 9 additional notification properties, all unsupported { DBPROP_ORDEREDBOOKMARKS, FALSE, eLocatable, -1 }, { DBPROP_OTHERINSERT, FALSE, eAsynchronous, -1 }, { DBPROP_OTHERUPDATEDELETE, FALSE, eAsynchronous, -1 }, { DBPROP_OWNINSERT, FALSE, eNotSupported, -1 }, { DBPROP_OWNUPDATEDELETE, FALSE, eNotSupported, -1 }, { DBPROP_QUICKRESTART, FALSE, eLocatable, -1 }, { DBPROP_REENTRANTEVENTS, FALSE, eDefaultFalse, -1 }, { DBPROP_REMOVEDELETED, FALSE, eDefaultTrue, -1 }, { DBPROP_REPORTMULTIPLECHANGES, FALSE, eNotSupported, -1 }, { DBPROP_RETURNPENDINGINSERTS, FALSE, eNotSupported, -1 }, { DBPROP_ROWRESTRICT, FALSE, eDefaultTrue, -1 }, { DBPROP_ROWTHREADMODEL, FALSE, eNumeric, -1 }, { DBPROP_SERVERCURSOR, FALSE, eDefaultTrue, -1 }, { DBPROP_STRONGIDENTITY, FALSE, eLocatable, -1 }, { DBPROP_TRANSACTEDOBJECT, FALSE, eColumnProp, -1 }, { DBPROP_UPDATABILITY, FALSE, eNumeric, -1 }, { DBPROP_ROWSET_ASYNCH, TRUE, eNumeric, eid_PROPVAL_ROWSET_ASYNCH }, // // Supported interfaces // { DBPROP_IAccessor, FALSE, eDefaultTrue, -1 }, { DBPROP_IColumnsInfo, FALSE, eDefaultTrue, -1 }, { DBPROP_IColumnsRowset, FALSE, eNotSupported, -1 }, { DBPROP_IConnectionPointContainer, FALSE, eDefaultTrue, -1 }, { DBPROP_IConvertType, FALSE, eDefaultTrue, -1 }, { DBPROP_IRowset, FALSE, eDefaultTrue, -1 }, { DBPROP_IRowsetIdentity, TRUE, eLocatable, eid_PROPVAL_IRowsetIdentity }, { DBPROP_IRowsetInfo, FALSE, eDefaultTrue, -1 }, { DBPROP_IRowsetLocate, TRUE, eLocatable, eid_PROPVAL_IRowsetLocate }, { DBPROP_IRowsetScroll, TRUE, eScrollable, eid_PROPVAL_IRowsetScroll }, { DBPROP_IRowsetExactScroll, TRUE, eScrollable, eid_PROPVAL_IRowsetExactScroll }, { DBPROP_IDBAsynchStatus, TRUE, eAsynchronous, eid_PROPVAL_IDBAsynchStatus }, { DBPROP_IRowsetAsynch, TRUE, eAsynchronous, eid_PROPVAL_IRowsetAsynch }, // deprecated { DBPROP_IRowsetWatchAll, TRUE, eWatchable, eid_PROPVAL_IRowsetWatchAll }, { DBPROP_IRowsetWatchRegion, TRUE, eWatchable, eid_PROPVAL_IRowsetWatchRegion }, { DBPROP_ISupportErrorInfo, FALSE, eDefaultTrue, -1 }, { DBPROP_IChapteredRowset, FALSE, eChaptered, -1 }, }; const ULONG CMRowsetProps::cPropDescriptions = sizeof CMRowsetProps::aPropDescriptions / sizeof CMRowsetProps::aPropDescriptions[0]; // // This array gives the Index Server property extensions // const SPropDescription CMRowsetProps::aQueryExtPropDescriptions[] = { { DBPROP_USECONTENTINDEX, TRUE, eUseCI, eid_PROPVAL_USECONTENTINDEX }, { DBPROP_DEFERNONINDEXEDTRIMMING, TRUE, eDeferTrimming, eid_PROPVAL_DEFERNONINDEXEDTRIMMING }, { DBPROP_USEEXTENDEDDBTYPES, TRUE, eExtendedTypes, eid_PROPVAL_USEEXTENDEDDBTYPES }, }; const ULONG CMRowsetProps::cQueryExtPropDescriptions = sizeof CMRowsetProps::aQueryExtPropDescriptions / sizeof CMRowsetProps::aQueryExtPropDescriptions[0]; // // This is used by CMRowsetProps. // static const UPROPSET s_rgRowsetPropSets[] = { &DBPROPSET_ROWSET, NUMELEM(s_rgdbPropRowset), s_rgdbPropRowset, 0, &DBPROPSET_MSIDXS_ROWSET_EXT, NUMELEM(s_rgdbPropMSIDXSExt), s_rgdbPropMSIDXSExt, 0, &DBPROPSET_QUERY_EXT, NUMELEM(s_rgdbPropQueryExt), s_rgdbPropQueryExt, 0, }; // // CMRowsetProps methods // //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::CMRowsetProps, public // // Synopsis: Constructor // // History: 11-12-97 danleg Created from Monarch // //---------------------------------------------------------------------------- CMRowsetProps::CMRowsetProps ( LCID lcidInit ) : CUtlProps(ARGCHK_PROPERTIESINERROR), _dwBooleanOptions ( 0) { if ( lcidInit ) _lcidInit = lcidInit; else _lcidInit = GetSystemDefaultLCID(); FInit(); } //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::CMRowsetProps, public // // Synopsis: Copy Constructor // // History: 11-12-97 danleg Created from Monarch // //---------------------------------------------------------------------------- CMRowsetProps::CMRowsetProps ( const CMRowsetProps & propSrc ) : CUtlProps(ARGCHK_PROPERTIESINERROR) { FInit( (CUtlProps*) &propSrc ); _lcidInit = propSrc._lcidInit; _dwBooleanOptions = propSrc._dwBooleanOptions; } //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::SetChaptered, public // // Arguments: [fSet] - set or unset this property // // Synopsis: // // History: 02-20-98 danleg Created // //---------------------------------------------------------------------------- DWORD CMRowsetProps::SetChaptered( BOOL fSet ) { SetValBool( CMRowsetProps::eid_DBPROPSET_ROWSET, CMRowsetProps::eid_PROPVAL_IChapteredRowset, fSet ? VARIANT_TRUE : VARIANT_FALSE ); if ( fSet ) _dwBooleanOptions |= eChaptered; else _dwBooleanOptions &= ~eChaptered; return _dwBooleanOptions; } //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::SetFirstRows, public // // Arguments: [ulFirstRows] - value of first rows // // Synopsis: Sets the FirstRows property // // History: 07-11-2000 KitmanH Created // //---------------------------------------------------------------------------- void CMRowsetProps::SetFirstRows( ULONG ulFirstRows ) { SetValLong( CMRowsetProps::eid_DBPROPSET_ROWSET, CMRowsetProps::eid_PROPVAL_FIRSTROWS, ulFirstRows ); _dwBooleanOptions |= eFirstRows; } //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::SetImpliedProperties, public // // Arguments: [riidRowset] - iid requested // [cRowsets] - indication on whethere this is a chaptered // rowset // Synopsis: This routine does not set any properties in the property table. // // History: 02-20-98 danleg Created // //---------------------------------------------------------------------------- DWORD CMRowsetProps::SetImpliedProperties ( REFIID riidRowset, ULONG cRowsets ) { SPropDescription const * pPropDesc = FindInterfaceDescription( riidRowset ); if ( pPropDesc == 0 ) THROW( CException(E_NOINTERFACE) ); if ( pPropDesc->fSettable ) { Win4Assert( pPropDesc->dwIndicator >= eSequential && pPropDesc->dwIndicator <= eWatchable ); _dwBooleanOptions |= pPropDesc->dwIndicator; // make sure that the eid_ in aPropDescriptions is in the range Win4Assert( pPropDesc->uIndex < eid_PROPVAL_ROWSET_NUM ); // // Set this property in the CMRowsetProps cache so we can later return it. // SetValBool( eid_DBPROPSET_ROWSET, pPropDesc->uIndex, VARIANT_TRUE ); } else if ( pPropDesc->dwIndicator != eDefaultTrue && !(pPropDesc->dwIndicator & _dwBooleanOptions) ) { THROW( CException(E_NOINTERFACE) ); } else { Win4Assert( pPropDesc->dwProp == DBPROP_IRowset || riidRowset == IID_IRowsetIdentity || riidRowset == IID_IRowsetInfo || riidRowset == IID_IColumnsInfo || riidRowset == IID_IConvertType || riidRowset == IID_IAccessor || riidRowset == IID_IConnectionPointContainer ); _dwBooleanOptions |= eSequential; } if ( cRowsets > 1 ) _dwBooleanOptions |= eChaptered; // // Interface indicators are arranged in a hierarchy from most general // to most specialized. Arrange that all more general interfaces are // included in the properties. // for ( unsigned i = eWatchable; i > eSequential; i = (i >> 1) ) { if ( _dwBooleanOptions & i ) _dwBooleanOptions |= (i >> 1); } Win4Assert( _dwBooleanOptions & eSequential ); // // Scrollable // IRowsetScroll or IRowsetExactScroll were set. IRowsetLocate is implied. // if ( _dwBooleanOptions & eScrollable ) { // IRowsetScroll is user settable. Make sure that it wasn't explicitly unset. if ( DBPROPOPTIONS_REQUIRED != GetPropOption( eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetScroll) ) { SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetScroll, VARIANT_TRUE ); SetPropOption( eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetScroll, DBPROPOPTIONS_REQUIRED ); } // IRowsetLocate is settable. Make sure it wasn't explicitly unset. if ( DBPROPOPTIONS_REQUIRED != GetPropOption( eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetLocate) ) { DWORD dwOption = GetPropOption( eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetScroll); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetLocate, VARIANT_TRUE ); SetPropOption( eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetLocate, dwOption ); } } // // Locatable // if ( _dwBooleanOptions & eLocatable ) { // these are not user settable SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_CANFETCHBACKWARDS, VARIANT_TRUE ); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_CANSCROLLBACKWARDS, VARIANT_TRUE ); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_LITERALIDENTITY, VARIANT_TRUE ); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_ORDEREDBOOKMARKS, VARIANT_TRUE ); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_QUICKRESTART, VARIANT_TRUE ); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_STRONGIDENTITY, VARIANT_TRUE ); // eLocateable (IRowsetLocate or IRowsetIdentity are set). IRowsetLocate implies BOOKMARKS if ( VARIANT_TRUE == GetValBool(eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetLocate) ) { // BOOKMARKs is settable. Make sure it hasn't already been set to FALSE/REQUIRED if ( DBPROPOPTIONS_REQUIRED != GetPropOption( eid_DBPROPSET_ROWSET, eid_PROPVAL_BOOKMARKS) ) { DWORD dwOption = GetPropOption( eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetLocate ); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_BOOKMARKS, VARIANT_TRUE ); SetPropOption( eid_DBPROPSET_ROWSET, eid_PROPVAL_BOOKMARKS, dwOption ); } } } else { SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_CANFETCHBACKWARDS, VARIANT_FALSE ); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_CANSCROLLBACKWARDS, VARIANT_FALSE ); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_LITERALIDENTITY, VARIANT_FALSE ); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_ORDEREDBOOKMARKS, VARIANT_FALSE ); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_QUICKRESTART, VARIANT_FALSE ); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_STRONGIDENTITY, VARIANT_FALSE ); } // // Asynchronous // if ( _dwBooleanOptions & eAsynchronous ) { SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_OTHERINSERT, VARIANT_TRUE ); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_OTHERUPDATEDELETE, VARIANT_TRUE ); } else { SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_OTHERINSERT, VARIANT_FALSE ); SetValBool( eid_DBPROPSET_ROWSET, eid_PROPVAL_OTHERUPDATEDELETE, VARIANT_FALSE ); } return _dwBooleanOptions; } //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::FindPropertyDescription, private // // Synopsis: Return description of a propery. // // Arguments: [rgPropDesc] - array of property descriptions for propset // [cPropDesc] - count of property descriptions in rgPropDesc // [dwPropId] - ID of the property description desired // // Returns: pointer to SPropDescription or NULL // // History: 19 Nov 95 AlanW Created // //---------------------------------------------------------------------------- SPropDescription const * CMRowsetProps::FindPropertyDescription( SPropDescription const * rgPropDesc, unsigned cPropDesc, DBPROPID dwPropId ) { SPropDescription const * pPropDesc = rgPropDesc; for (unsigned i=0; i < cPropDesc; i++, pPropDesc++) { if (pPropDesc->dwProp == dwPropId) return pPropDesc; } return 0; } const struct SIidLookup { const GUID * riid; DBPROPID dwPropId; } aIidLookup[] = { { &IID_IAccessor, DBPROP_IAccessor }, { &IID_IColumnsInfo, DBPROP_IColumnsInfo }, { &IID_IColumnsRowset, DBPROP_IColumnsRowset }, { &IID_IConnectionPointContainer, DBPROP_IConnectionPointContainer }, { &IID_IConvertType, DBPROP_IConvertType }, // { &IID_ICopyColumn, DBPROP_ICopyColumn }, { &IID_IRowset, DBPROP_IRowset }, { &IID_IRowsetIdentity, DBPROP_IRowsetIdentity }, { &IID_IRowsetInfo, DBPROP_IRowsetInfo }, { &IID_IRowsetLocate, DBPROP_IRowsetLocate }, { &IID_IRowsetScroll, DBPROP_IRowsetScroll }, { &IID_IRowsetExactScroll, DBPROP_IRowsetExactScroll }, // deprecated { &IID_IDBAsynchStatus, DBPROP_IDBAsynchStatus }, { &IID_IRowsetAsynch, DBPROP_IRowsetAsynch }, // deprecated { &IID_IRowsetWatchAll, DBPROP_IRowsetWatchAll }, { &IID_IRowsetWatchRegion, DBPROP_IRowsetWatchRegion }, { &IID_IUnknown, DBPROP_IRowset }, { &IID_NULL, DBPROP_IRowset }, }; const unsigned cIidLookup = sizeof aIidLookup / sizeof aIidLookup[0]; //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::FindInterfaceDescription, private // // Synopsis: Return property description corresponding to an interface // // Arguments: [riid] - REFIID of interface to be looked up // // Returns: pointer to SPropDescription or NULL // // History: 26 Sep 96 AlanW Created // //---------------------------------------------------------------------------- SPropDescription const * CMRowsetProps::FindInterfaceDescription( REFIID riid ) { for (unsigned i=0; i < cIidLookup; i++) { if (riid == *aIidLookup[i].riid) return FindPropertyDescription( aPropDescriptions, cPropDescriptions, aIidLookup[i].dwPropId ); } return 0; } //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::UpdateBooleanOptions, private // // Synopsis: Update _dwBooleanOptions to reflect newly set properties. // Look for conflicting properties and mark them as such. // // History: 03-02-98 danleg Created // //---------------------------------------------------------------------------- void CMRowsetProps::UpdateBooleanOptions ( const ULONG cPropertySets, const DBPROPSET rgPropertySets[] ) { SCODE sc = S_OK; DWORD dwSetOptions = 0; DWORD dwUnsetOptions = 0; DWORD dwOption = 0; // // table for boolean options // for ( unsigned i=0; idwStatus ) { // // determine the flag to set for this property // SPropDescription const * pFoundDesc = FindPropertyDescription ( pPropDesc, cPropDesc, pProp->dwPropertyID ); if ( 0 != pFoundDesc ) { // Setting read-only props to their default value succeeds if ( !pFoundDesc->fSettable ) continue; dwOption = pFoundDesc->dwIndicator; // // Settable properties with special option flags // switch ( pProp->dwPropertyID ) { case DBPROP_COMMANDTIMEOUT: case DBPROP_MAXROWS: case DBPROP_MEMORYUSAGE: continue; case DBPROP_FIRSTROWS: dwOption = eFirstRows; break; case DBPROP_ROWSET_ASYNCH: dwOption = eAsynchronous; break; default: // no other settable props that need special handling break; } // // determine if the property was set or unset // switch ( V_VT(&(pProp->vValue)) ) { case VT_BOOL: if ( VARIANT_FALSE == V_BOOL(&(pProp->vValue)) ) dwUnsetOptions |= dwOption; else dwSetOptions |= dwOption; break; case VT_I4: if ( DBPROPSET_ROWSET == rgPropertySets[i].guidPropertySet && ( DBPROP_ROWSET_ASYNCH == pProp->dwPropertyID || DBPROP_FIRSTROWS == pProp->dwPropertyID ) ) { if ( 0 == V_I4(&(pProp->vValue)) ) dwUnsetOptions |= dwOption; else dwSetOptions |= dwOption; } break; case VT_EMPTY: // assume to mean unset dwUnsetOptions |= dwOption; break; default: break; } } else { // This should never get hit since the property was set successfully. Win4Assert( ! "_rgdbPropRowset and aPropDescriptions are out of sync." ); } } } } Win4Assert( (dwSetOptions & dwUnsetOptions) == 0 ); if ( dwSetOptions & eScrollable ) { dwUnsetOptions |= eSequential; } else if ( dwSetOptions & eSequential ) { dwUnsetOptions |= eScrollable; } // // If IRowsetLocate and/or BOOKMARKS were explicitly set, and // IRowsetIdentity is being unset, don't take of the eLocatable bit // if ( dwUnsetOptions & eLocatable ) { if ( VARIANT_TRUE == GetValBool(eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetLocate) || VARIANT_TRUE == GetValBool(eid_DBPROPSET_ROWSET, eid_PROPVAL_BOOKMARKS) ) dwUnsetOptions &= ~eLocatable; } _dwBooleanOptions &= ~dwUnsetOptions; _dwBooleanOptions |= dwSetOptions; } //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::SetProperties, public // // Synopsis: // // History: 02-15-98 danleg Created // //---------------------------------------------------------------------------- SCODE CMRowsetProps::SetProperties ( const ULONG cPropertySets, const DBPROPSET rgPropertySets[] ) { SCODE sc = S_OK; ULONG cPropSets = cPropertySets; sc = CUtlProps::SetProperties( cPropertySets, rgPropertySets ); if ( FAILED(sc) ) return sc; // // Some or all of the properties were set successfully. // Update _dwBooleanOptions. // UpdateBooleanOptions( cPropertySets, rgPropertySets ); return sc; } //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::ArePropsInError, public // // Synopsis: Update _dwBooleanOptions to reflect newly set properties. // Look for conflicting properties and mark them as such. // // History: 03-02-98 danleg Created // //---------------------------------------------------------------------------- SCODE CMRowsetProps::ArePropsInError ( CMRowsetProps & rProps ) { unsigned cErrors = 0; // // DBPROP_IRowsetScroll --> DBPROP_IRowsetLocate // if( VARIANT_TRUE == GetValBool(eid_DBPROPSET_ROWSET,eid_PROPVAL_IRowsetScroll) && DBPROPOPTIONS_REQUIRED == GetPropOption(eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetScroll) ) { // IRowsetLocate should also be set to TRUE/REQUIRED if ( VARIANT_FALSE == GetValBool(eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetLocate) && DBPROPOPTIONS_REQUIRED == GetPropOption(eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetLocate) ) { rProps.SetPropertyInError( eid_DBPROPSET_ROWSET, eid_PROP_IRowsetScroll ); rProps.SetPropertyInError( eid_DBPROPSET_ROWSET, eid_PROP_IRowsetLocate ); cErrors++; } // BOOKMARKS should also be set to TRUE/REQUIRED if ( VARIANT_FALSE == GetValBool(eid_DBPROPSET_ROWSET, eid_PROPVAL_BOOKMARKS) && DBPROPOPTIONS_REQUIRED == GetPropOption(eid_DBPROPSET_ROWSET, eid_PROPVAL_BOOKMARKS) ) { rProps.SetPropertyInError( eid_DBPROPSET_ROWSET, eid_PROP_BOOKMARKS ); rProps.SetPropertyInError( eid_DBPROPSET_ROWSET, eid_PROP_IRowsetScroll ); cErrors++; } } // // DBPROP_IRowsteLocate --> DBPROP_BOOKMARKS // if( VARIANT_TRUE == GetValBool(eid_DBPROPSET_ROWSET,eid_PROPVAL_IRowsetLocate) && DBPROPOPTIONS_REQUIRED == GetPropOption(eid_DBPROPSET_ROWSET, eid_PROPVAL_IRowsetLocate) ) { // BOOKMARKS should also be set to TRUE/REQUIRED if ( VARIANT_FALSE == GetValBool(eid_DBPROPSET_ROWSET, eid_PROPVAL_BOOKMARKS) && DBPROPOPTIONS_REQUIRED == GetPropOption(eid_DBPROPSET_ROWSET, eid_PROPVAL_BOOKMARKS) ) { rProps.SetPropertyInError( eid_DBPROPSET_ROWSET, eid_PROP_BOOKMARKS ); rProps.SetPropertyInError( eid_DBPROPSET_ROWSET, eid_PROP_IRowsetLocate ); cErrors++; } } return ( cErrors ) ? DB_E_ERRORSOCCURRED : S_OK; } //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::InitAvailUPropsets, private // // Synopsis: Provide property set information to the base class // // History: 11-12-97 danleg Created from Monarch // //---------------------------------------------------------------------------- SCODE CMRowsetProps::InitAvailUPropSets ( ULONG* pcUPropSet, UPROPSET** ppUPropSet, ULONG* pcElemPerSupported ) { Win4Assert( pcUPropSet && ppUPropSet); Win4Assert( NUMELEM(s_rgdbPropRowset) == eid_ROWSET_PROPS_NUM ); Win4Assert( NUMELEM(s_rgdbPropQueryExt) == eid_QUERYEXT_PROPS_NUM ); Win4Assert( NUMELEM(s_rgdbPropMSIDXSExt) == eid_MSIDXS_PROPS_NUM ); *pcUPropSet = NUMELEM(s_rgRowsetPropSets); *ppUPropSet = (UPROPSET*)s_rgRowsetPropSets; *pcElemPerSupported = DWORDSNEEDEDPERSET; return S_OK; } //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::InitUPropSetsSupported, private // // Synopsis: Build the required supported property bitmask for the property // set supported by this class // // History: 11-12-97 danleg Created from Monarch // //---------------------------------------------------------------------------- SCODE CMRowsetProps::InitUPropSetsSupported ( DWORD* rgdwSupported ) { Win4Assert( rgdwSupported ); // Initialize the bitmask to indicate all properties are supported RtlFillMemory( rgdwSupported, DWORDSNEEDEDPERSET * NUMELEM(s_rgRowsetPropSets) * sizeof(DWORD), 0xFF ); return S_OK; } //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::GetDefaultValue, private // // Synopsis: Retrieve the initial value for a propid. // DEVNOTE: Using the index from 0 to (GetCountofAvailPropSets-1) // and an index of 0 to (GetCountofAvailPropidsInPropset-1) // within that propertyset, return the correct information. // NOTE: pVar should be initialized prior to this routine. // // History: 11-12-97 danleg Created from Monarch // //---------------------------------------------------------------------------- SCODE CMRowsetProps::GetDefaultValue ( ULONG iCurSet, DBPROPID dwPropId, DWORD* pdwOption, VARIANT* pvValue ) { Win4Assert( V_VT(pvValue) == VT_EMPTY ); switch( iCurSet ) { case eid_DBPROPSET_ROWSET: *pdwOption = DBPROPOPTIONS_REQUIRED; switch ( dwPropId ) { // default TRUE values, non-writable case DBPROP_IAccessor: case DBPROP_IColumnsInfo: case DBPROP_IConnectionPointContainer: case DBPROP_IConvertType: case DBPROP_IRowset: case DBPROP_IRowsetInfo: case DBPROP_ISupportErrorInfo: case DBPROP_REMOVEDELETED: case DBPROP_ROWRESTRICT: case DBPROP_SERVERCURSOR: V_VT( pvValue ) = VT_BOOL; V_BOOL( pvValue ) = VARIANT_TRUE; break; case DBPROP_IChapteredRowset: V_VT( pvValue ) = VT_BOOL; V_BOOL( pvValue ) = VARIANT_FALSE; break; // default FALSE non-writable case DBPROP_BLOCKINGSTORAGEOBJECTS: case DBPROP_BOOKMARKSKIPPED: case DBPROP_CANFETCHBACKWARDS: case DBPROP_CANSCROLLBACKWARDS: case DBPROP_COLUMNRESTRICT: case DBPROP_LITERALBOOKMARKS: case DBPROP_LITERALIDENTITY: case DBPROP_ORDEREDBOOKMARKS: case DBPROP_OTHERINSERT: case DBPROP_OTHERUPDATEDELETE: case DBPROP_REENTRANTEVENTS: case DBPROP_STRONGIDENTITY: case DBPROP_QUICKRESTART: V_VT( pvValue ) = VT_BOOL; V_BOOL( pvValue ) = VARIANT_FALSE; break; // default FALSE, writable case DBPROP_BOOKMARKS: case DBPROP_CANHOLDROWS: case DBPROP_IDBAsynchStatus: case DBPROP_IRowsetAsynch: case DBPROP_IRowsetExactScroll: case DBPROP_IRowsetIdentity: case DBPROP_IRowsetScroll: case DBPROP_IRowsetWatchAll: case DBPROP_IRowsetWatchRegion: case DBPROP_IRowsetLocate: *pdwOption = DBPROPOPTIONS_OPTIONAL; V_VT( pvValue ) = VT_BOOL; V_BOOL( pvValue ) = VARIANT_FALSE; break; case DBPROP_BOOKMARKTYPE: V_VT( pvValue ) = VT_I4; V_I4( pvValue ) = DBPROPVAL_BMK_NUMERIC; break; case DBPROP_COMMANDTIMEOUT: case DBPROP_MAXOPENROWS: case DBPROP_MAXROWS: case DBPROP_FIRSTROWS: case DBPROP_MEMORYUSAGE: case DBPROP_ROWSET_ASYNCH: case DBPROP_UPDATABILITY: V_VT( pvValue ) = VT_I4; V_I4( pvValue ) = 0; break; case DBPROP_ROWTHREADMODEL: V_VT( pvValue ) = VT_I4; V_I4( pvValue ) = DBPROPVAL_RT_FREETHREAD; break; case DBPROP_NOTIFICATIONPHASES: V_VT( pvValue ) = VT_I4; V_I4( pvValue ) = DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_FAILEDTODO | DBPROPVAL_NP_DIDEVENT; break; case DBPROP_NOTIFYROWSETRELEASE: V_VT( pvValue ) = VT_I4; V_I4( pvValue ) = 0; break; case DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE: V_VT( pvValue ) = VT_I4; V_I4( pvValue ) = DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO; break; case DBPROP_CACHEDEFERRED: case DBPROP_DEFERRED: default: // one of the unsupported properties VariantClear( pvValue ); break; } break; case eid_DBPROPSET_QUERY_EXT: *pdwOption = DBPROPOPTIONS_REQUIRED; // // All three properties under this property set are BOOL/FALSE by default // V_VT( pvValue ) = VT_BOOL; V_BOOL( pvValue ) = VARIANT_FALSE; break; case eid_DBPROPSET_MSIDXS_ROWSET_EXT: *pdwOption = DBPROPOPTIONS_REQUIRED; switch( dwPropId ) { case MSIDXSPROP_ROWSETQUERYSTATUS: V_VT(pvValue) = VT_I4; V_I4(pvValue) = 0; break; case MSIDXSPROP_COMMAND_LOCALE_STRING: *pdwOption = DBPROPOPTIONS_OPTIONAL; V_VT(pvValue) = VT_BSTR; WCHAR awcLocale[100]; GetStringFromLCID(_lcidInit, awcLocale ); V_BSTR(pvValue) = SysAllocString( awcLocale ); if ( 0 == V_BSTR(pvValue) ) return E_OUTOFMEMORY; break; case MSIDXSPROP_QUERY_RESTRICTION: V_VT(pvValue) = VT_BSTR; V_BSTR(pvValue) = SysAllocString(L""); if ( 0 == V_BSTR(pvValue) ) return E_OUTOFMEMORY; break; default: //Indicate that value is unknown VariantClear(pvValue); break; } break; default: // Invalid Property Set Win4Assert( ! "Invalid property set in GetDefaultValue."); return E_FAIL; } return S_OK; } //+--------------------------------------------------------------------------- // // Method: CMRowsetProps::IsValidValue, private // // Synopsis: Validate that the variant contains legal values for its // particular type and for the particular PROPID in this propset. // Devnote: This routine has to apply to writable properties only. // // History: 11-12-97 danleg Created from Monarch // 02-01-98 danleg Added support for DBPROPSET_ROWSET // and DBPROPSET_QUERYEXT // //---------------------------------------------------------------------------- SCODE CMRowsetProps::IsValidValue ( ULONG iCurSet, DBPROP* pDBProp ) { switch ( V_VT(&(pDBProp->vValue)) ) { case VT_BOOL: if ( !( VARIANT_TRUE == V_BOOL(&(pDBProp->vValue)) || VARIANT_FALSE == V_BOOL(&(pDBProp->vValue)) ) ) return S_FALSE; break; case VT_I4: switch ( iCurSet ) { case eid_DBPROPSET_ROWSET: switch ( pDBProp->dwPropertyID ) { case DBPROP_BOOKMARKTYPE: if ( !(DBPROPVAL_BMK_NUMERIC == V_I4(&(pDBProp->vValue)) || DBPROPVAL_BMK_KEY == V_I4(&(pDBProp->vValue)) ) ) return S_FALSE; break; case DBPROP_ROWSET_ASYNCH: switch ( V_I4(&(pDBProp->vValue)) ) { case ( DBPROPVAL_ASYNCH_SEQUENTIALPOPULATION | DBPROPVAL_ASYNCH_RANDOMPOPULATION ): case DBPROPVAL_ASYNCH_RANDOMPOPULATION: case 0: // means sequential init and population break; case DBPROPVAL_ASYNCH_INITIALIZE: case DBPROPVAL_ASYNCH_SEQUENTIALPOPULATION: default: return S_FALSE; } break; case DBPROP_ROWTHREADMODEL: // this is a r/o property, set to FREETHREAD by default. switch ( V_I4(&(pDBProp->vValue)) ) { case DBPROPVAL_RT_FREETHREAD: case DBPROPVAL_RT_APTMTTHREAD: case DBPROPVAL_RT_SINGLETHREAD: break; default: return S_FALSE; } break; case DBPROP_MEMORYUSAGE: if ( 0 > V_I4(&(pDBProp->vValue)) || 99 < V_I4(&(pDBProp->vValue)) ) return S_FALSE; break; case DBPROP_COMMANDTIMEOUT: case DBPROP_MAXROWS: case DBPROP_FIRSTROWS: if ( 0 > V_I4(&(pDBProp->vValue)) ) return S_FALSE; break; case DBPROP_UPDATABILITY: // this is the only other supported VT_I4 property break; default: // no other VT_I4 properties in DBPROPSET_ROWSET return S_FALSE; } break; case eid_DBPROPSET_MSIDXS_ROWSET_EXT: if ( MSIDXSPROP_ROWSETQUERYSTATUS != pDBProp->dwPropertyID ) return S_FALSE; break; default: return S_FALSE; } break; // VT_I4 case VT_BSTR: switch ( iCurSet ) { case eid_DBPROPSET_MSIDXS_ROWSET_EXT: switch ( pDBProp->dwPropertyID ) { case MSIDXSPROP_COMMAND_LOCALE_STRING: if ( 0 == V_BSTR(&(pDBProp->vValue)) || InvalidLCID == GetLCIDFromString(V_BSTR(&(pDBProp->vValue))) ) return S_FALSE; break; case MSIDXSPROP_QUERY_RESTRICTION: // any bstr is valid break; default: // there are no other bstr properties in this property set return S_FALSE; } break; default: // the other two prop sets don't have any VT_BSTR properties return S_FALSE; } break; case VT_EMPTY: // always valid break; default: // no other types are supported return S_FALSE; } return S_OK; // Is valid }