/****************************************************************************** * $Id: ICommandWithParametersImpl.h,v 1.3 2001/10/15 13:38:11 warmerda Exp $ * * Project: OpenGIS Simple Features Reference Implementation * Purpose: ICommandWithParameters implementation template. * * This code was provided as a sample by Jillian Clark at ESRI, and is * free to use, but did not come with an explicit copyright message so the * following was inserted. Some changes have been made to the version * provided by Jillian (reimplementing use of CArray for instance). * ****************************************************************************** * Copyright (c) 2001, ESRI (www.esri.com) * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: ICommandWithParametersImpl.h,v $ * Revision 1.3 2001/10/15 13:38:11 warmerda * change to unix text format * * Revision 1.2 2001/08/17 19:58:21 warmerda * remove LFs * * Revision 1.1 2001/08/17 14:23:43 warmerda * New * */ #ifndef __I_COMMAND_WITH_PARAMETERS_IMPL__INCLUDED__ #define __I_COMMAND_WITH_PARAMETERS_IMPL__INCLUDED__ #include #include /////////////////////////////////////////////////////////////////////////// // class ICommandWithParametersImpl static const struct StandardDataType { const OLECHAR *typeName; DBTYPE dbType; } standardDataTypes[] = { { OLESTR("DBTYPE_I2"), DBTYPE_I2 }, { OLESTR("DBTYPE_UI2"), DBTYPE_I2 }, { OLESTR("DBTYPE_I4"), DBTYPE_I4 }, { OLESTR("DBTYPE_UI4"), DBTYPE_UI4 }, { OLESTR("DBTYPE_R4"), DBTYPE_R4 }, { OLESTR("DBTYPE_R8"), DBTYPE_R8 }, { OLESTR("DBTYPE_BOOL"), DBTYPE_I2 }, { OLESTR("DBTYPE_VARIANT"), DBTYPE_VARIANT }, { OLESTR("DBTYPE_IUNKNOWN"), DBTYPE_IUNKNOWN }, { OLESTR("DBTYPE_DATE"), DBTYPE_DATE }, { OLESTR("DBTYPE_BSTR"), DBTYPE_BSTR }, { OLESTR("DBTYPE_CHAR"), DBTYPE_BSTR }, { OLESTR("DBTYPE_WSTR"), DBTYPE_BSTR }, { OLESTR("DBTYPE_VARCHAR"), DBTYPE_BSTR }, { OLESTR("DBTYPE_LONGVARCHAR"), DBTYPE_BSTR }, { OLESTR("DBTYPE_WCHAR"), DBTYPE_BSTR }, { OLESTR("DBTYPE_BINARY"), DBTYPE_IUNKNOWN }, { OLESTR("DBTYPE_VARBINARY"), DBTYPE_IUNKNOWN }, { OLESTR("DBTYPE_LONGVARBINARY"), DBTYPE_IUNKNOWN }, { OLESTR("DBTYPE_GEOMETRY"), DBTYPE_IUNKNOWN }, { OLESTR("DBTYPE_VARIANT"), DBTYPE_VARIANT } }; template class ATL_NO_VTABLE ICommandWithParametersImpl : public ICommandWithParameters { public: ICommandWithParametersImpl(void) : m_nSetParams(0) { } STDMETHOD(GetParameterInfo)( ULONG *pcParams, DBPARAMINFO **prgParamInfo, OLECHAR **ppNamesBuffer) { CPLDebug( "OGR_OLEDB", "ICommandWithParameterImpl::GetParametersInfo"); HRESULT hr = E_FAIL; if (!pcParams || !prgParamInfo || !ppNamesBuffer) { CPLDebug( "OGR_OLEDB", "ICommandWithParameterImpl::GetParametersInfo: - Error - a pointer is null\n"); return E_INVALIDARG; } T *pT = 0; *pcParams = 0; // The way that we use the command parameters means that this never gets called... return DB_E_PARAMUNAVAILABLE; } STDMETHOD(MapParameterNames)( ULONG cParamNames, const OLECHAR *rgParamNames[], LONG rgParamOrdinals[]) { CPLDebug( "OGR_OLEDB", "ICommandWithParametersImpl::MapParameterNames\n"); if( cParamNames == 0 ) return S_OK; if (cParamNames > 0 && (rgParamNames == 0 || rgParamOrdinals == 0)) return E_INVALIDARG; for (ULONG i = 0; i < cParamNames; i++) { rgParamOrdinals[i] = GetSpatialParamOrdinal(rgParamNames[i]); } return S_OK; } STDMETHOD(SetParameterInfo)( ULONG cParams, const ULONG rgParamOrdinals[], const DBPARAMBINDINFO rgParamBindInfo[]) { CPLDebug("OGR_OLEDB", "ICommandWithParametersImpl::SetParameterInfo\n"); HRESULT hr; if (cParams == 0) { for( int i=0; i < (int) m_nSetParams; i++ ) delete m_apParamInfo[i]; m_nSetParams = 0; return S_OK; } if (cParams > 0 && rgParamOrdinals == 0) return E_INVALIDARG; if (rgParamBindInfo != 0) { bool allParamNamesSet = true, oneParamNameSet = false; for (ULONG i = 0; i < cParams; i++) { // We do not handle default parameter conversion if (rgParamBindInfo[i].pwszDataSourceType == 0) return E_INVALIDARG; DBTYPE dbType; if ((dbType = CheckDataType(rgParamBindInfo[i].pwszDataSourceType)) == DBTYPE_EMPTY) return DB_E_BADTYPENAME; if( rgParamBindInfo[i].pwszName == 0 ) allParamNamesSet = false; else oneParamNameSet = true; if( rgParamBindInfo[i].dwFlags & ~(DBPARAMIO_INPUT | DBPARAMIO_OUTPUT) ) return E_INVALIDARG; } if( oneParamNameSet && ! allParamNamesSet ) return DB_E_BADPARAMETERNAME; } for (ULONG i = 0; i < cParams; i++) { // Look for the parameter already in the list for (int j = m_nSetParams; --j >= 0;) { if( rgParamOrdinals[i] == m_apParamInfo[j]->iOrdinal ) break; } if (j >= 0) { // Discard the type info. for this parameter if( rgParamBindInfo == 0 ) { delete m_apParamInfo[j]; while( j < (int)m_nSetParams ) { m_apParamInfo[j] = m_apParamInfo[j + 1]; j++; } --m_nSetParams; } // Change parameter type info??? else { } } else if (rgParamBindInfo != 0) { m_apParamInfo[m_nSetParams] = new ParamInfo(); ParamInfo ¶mInfo = *(m_apParamInfo[m_nSetParams]); if (FAILED(hr = paramInfo.Set( rgParamOrdinals[i], rgParamBindInfo[i]))) return hr; m_nSetParams++; } } return S_OK; } static DBTYPE CheckDataType( const OLECHAR *pDataTypeName ) { const StandardDataType *pDataTypes = standardDataTypes; ATLASSERT(pDataTypeName); for (int i = sizeof(standardDataTypes)/sizeof(standardDataTypes[0]); --i >= 0;) { if (::wcsicmp( pDataTypes->typeName, pDataTypeName) == 0) return pDataTypes->dbType; pDataTypes++; } return DBTYPE_EMPTY; } protected: static ULONG GetSpatialParamOrdinal(const OLECHAR *paramName) { static const OLECHAR *paramNames[] = { OLESTR( "SPATIAL_FILTER" ), OLESTR( "SPATIAL_OPERATOR" ), OLESTR( "SPATIAL_GEOM_COL_NAME" ) }; for (int i = 0; i < sizeof(paramNames)/sizeof(paramNames[0]); i++) { if (::wcsicmp(paramNames[i], paramName) == 0) { return i + 1; } } return 0; } struct ParamInfo : public DBPARAMINFO { ParamInfo(void) { this->iOrdinal = 0; this->pwszName = 0; this->ulParamSize = 0; this->dwFlags = DBPARAMFLAGS_ISINPUT; this->bPrecision = 0; this->bScale = 0; this->wType = 0; this->pTypeInfo = 0; } ~ParamInfo( void ) { if (this->pwszName != 0) delete [] this->pwszName; } HRESULT Set(ULONG ordinal, const DBPARAMBINDINFO &rParamBindInfo) { this->iOrdinal = ordinal; if (this->pwszName != 0) { delete [] this->pwszName; this->pwszName = 0; } if (rParamBindInfo.pwszName != 0) { this->pwszName = new OLECHAR[::wcslen( rParamBindInfo.pwszName ) + 1]; if (this->pwszName == 0) return E_OUTOFMEMORY; ::wcscpy( this->pwszName, rParamBindInfo.pwszName ); } ATLASSERT(rParamBindInfo.pwszDataSourceType); this->wType = CheckDataType(rParamBindInfo.pwszDataSourceType); this->ulParamSize = rParamBindInfo.ulParamSize; this->dwFlags = rParamBindInfo.dwFlags; this->bPrecision = rParamBindInfo.bPrecision; this->bScale = rParamBindInfo.bScale; return S_OK; } }; ParamInfo *m_apParamInfo[100]; ULONG m_nSetParams; }; #endif // __I_COMMAND_WITH_PARAMETERS_IMPL__INCLUDED__