diff options
Diffstat (limited to 'connectivity/source/commontools')
21 files changed, 992 insertions, 220 deletions
diff --git a/connectivity/source/commontools/ConnectionWrapper.cxx b/connectivity/source/commontools/ConnectionWrapper.cxx index 450243c0295c..8a4ee0272251 100644 --- a/connectivity/source/commontools/ConnectionWrapper.cxx +++ b/connectivity/source/commontools/ConnectionWrapper.cxx @@ -109,7 +109,7 @@ void OConnectionWrapper::setDelegation(const Reference< XConnection >& _xConnect // ----------------------------------------------------------------------------- void OConnectionWrapper::disposing() { - m_xConnection = NULL; +m_xConnection.clear(); } //----------------------------------------------------------------------------- OConnectionWrapper::~OConnectionWrapper() diff --git a/connectivity/source/commontools/DateConversion.cxx b/connectivity/source/commontools/DateConversion.cxx index e58e292bb91b..010cfbcf5f34 100644 --- a/connectivity/source/commontools/DateConversion.cxx +++ b/connectivity/source/commontools/DateConversion.cxx @@ -45,6 +45,7 @@ #include "TConnection.hxx" #include "diagnose_ex.h" #include <comphelper/numbers.hxx> +#include <rtl/ustrbuf.hxx> using namespace ::connectivity; @@ -63,7 +64,7 @@ using namespace ::com::sun::star::beans; ::rtl::OUString DBTypeConversion::toSQLString(sal_Int32 eType, const Any& _rVal, sal_Bool bQuote, const Reference< XTypeConverter >& _rxTypeConverter) { - ::rtl::OUString aRet; + ::rtl::OUStringBuffer aRet; if (_rVal.hasValue()) { try @@ -78,23 +79,28 @@ using namespace ::com::sun::star::beans; if (_rVal.getValueType().getTypeClass() == ::com::sun::star::uno::TypeClass_BOOLEAN) { if (::cppu::any2bool(_rVal)) - aRet = ::rtl::OUString::createFromAscii("1"); + aRet.appendAscii("1"); else - aRet = ::rtl::OUString::createFromAscii("0"); + aRet.appendAscii("0"); } else - _rxTypeConverter->convertToSimpleType(_rVal, TypeClass_STRING) >>= aRet; + { + ::rtl::OUString sTemp; + _rxTypeConverter->convertToSimpleType(_rVal, TypeClass_STRING) >>= sTemp; + aRet.append(sTemp); + } break; case DataType::CHAR: case DataType::VARCHAR: + case DataType::LONGVARCHAR: if (bQuote) - aRet += ::rtl::OUString::createFromAscii("'"); + aRet.appendAscii("'"); { ::rtl::OUString aTemp; _rxTypeConverter->convertToSimpleType(_rVal, TypeClass_STRING) >>= aTemp; sal_Int32 nIndex = (sal_Int32)-1; - ::rtl::OUString sQuot(RTL_CONSTASCII_USTRINGPARAM("\'")); - ::rtl::OUString sQuotToReplace(RTL_CONSTASCII_USTRINGPARAM("\'\'")); + const ::rtl::OUString sQuot(RTL_CONSTASCII_USTRINGPARAM("\'")); + const ::rtl::OUString sQuotToReplace(RTL_CONSTASCII_USTRINGPARAM("\'\'")); do { nIndex += 2; @@ -103,17 +109,22 @@ using namespace ::com::sun::star::beans; aTemp = aTemp.replaceAt(nIndex,sQuot.getLength(),sQuotToReplace); } while (nIndex != -1); - aRet += aTemp; + aRet.append(aTemp); } if (bQuote) - aRet += ::rtl::OUString::createFromAscii("'"); + aRet.appendAscii("'"); break; case DataType::REAL: case DataType::DOUBLE: case DataType::DECIMAL: case DataType::NUMERIC: case DataType::BIGINT: - _rxTypeConverter->convertToSimpleType(_rVal, TypeClass_STRING) >>= aRet; + default: + { + ::rtl::OUString sTemp; + _rxTypeConverter->convertToSimpleType(_rVal, TypeClass_STRING) >>= sTemp; + aRet.append(sTemp); + } break; case DataType::TIMESTAMP: { @@ -122,9 +133,11 @@ using namespace ::com::sun::star::beans; // check if this is really a timestamp or only a date if ( _rVal >>= aDateTime ) { - if (bQuote) aRet += ::rtl::OUString::createFromAscii("{TS '"); - aRet += DBTypeConversion::toDateTimeString(aDateTime); - if (bQuote) aRet += ::rtl::OUString::createFromAscii("'}"); + if (bQuote) + aRet.appendAscii("{TS '"); + aRet.append(DBTypeConversion::toDateTimeString(aDateTime)); + if (bQuote) + aRet.appendAscii("'}"); break; } break; @@ -133,20 +146,22 @@ using namespace ::com::sun::star::beans; { Date aDate; OSL_VERIFY_RES( _rVal >>= aDate, "DBTypeConversion::toSQLString: _rVal is not date!"); - if (bQuote) aRet += ::rtl::OUString::createFromAscii("{D '"); - aRet += DBTypeConversion::toDateString(aDate);; - if (bQuote) aRet += ::rtl::OUString::createFromAscii("'}"); + if (bQuote) + aRet.appendAscii("{D '"); + aRet.append(DBTypeConversion::toDateString(aDate)); + if (bQuote) + aRet.appendAscii("'}"); } break; case DataType::TIME: { Time aTime; OSL_VERIFY_RES( _rVal >>= aTime,"DBTypeConversion::toSQLString: _rVal is not time!"); - if (bQuote) aRet += ::rtl::OUString::createFromAscii("{T '"); - aRet += DBTypeConversion::toTimeString(aTime); - if (bQuote) aRet += ::rtl::OUString::createFromAscii("'}"); + if (bQuote) + aRet.appendAscii("{T '"); + aRet.append(DBTypeConversion::toTimeString(aTime)); + if (bQuote) + aRet.appendAscii("'}"); } break; - default: - _rxTypeConverter->convertToSimpleType(_rVal, TypeClass_STRING) >>= aRet; } } catch ( const Exception& ) @@ -155,8 +170,8 @@ using namespace ::com::sun::star::beans; } } else - aRet = ::rtl::OUString::createFromAscii(" NULL "); - return aRet; + aRet.appendAscii(" NULL "); + return aRet.makeStringAndClear(); } // ----------------------------------------------------------------------------- Date DBTypeConversion::getNULLDate(const Reference< XNumberFormatsSupplier > &xSupplier) diff --git a/connectivity/source/commontools/DriversConfig.cxx b/connectivity/source/commontools/DriversConfig.cxx new file mode 100755 index 000000000000..30c822b6f169 --- /dev/null +++ b/connectivity/source/commontools/DriversConfig.cxx @@ -0,0 +1,270 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: makefile,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: st $ $Date: 2000/11/22 02:32:00 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ +#include "connectivity/DriversConfig.hxx" +#include <tools/wldcrd.hxx> + +using namespace connectivity; +using namespace utl; +using namespace ::com::sun::star; + +namespace +{ + void lcl_convert(const uno::Sequence< ::rtl::OUString >& _aSource,uno::Any& _rDest) + { + uno::Sequence<uno::Any> aRet(_aSource.getLength()); + uno::Any* pAny = aRet.getArray(); + const ::rtl::OUString* pIter = _aSource.getConstArray(); + const ::rtl::OUString* pEnd = pIter + _aSource.getLength(); + for (;pIter != pEnd ; ++pIter,++pAny) + { + *pAny <<= *pIter; + } + _rDest <<= aRet; + } + void lcl_fillValues(const ::utl::OConfigurationNode& _aURLPatternNode,const ::rtl::OUString& _sNode,::comphelper::NamedValueCollection& _rValues) + { + const ::utl::OConfigurationNode aPropertiesNode = _aURLPatternNode.openNode(_sNode); + if ( aPropertiesNode.isValid() ) + { + uno::Sequence< ::rtl::OUString > aStringSeq; + static const ::rtl::OUString s_sValue(RTL_CONSTASCII_USTRINGPARAM("/Value")); + const uno::Sequence< ::rtl::OUString > aProperties = aPropertiesNode.getNodeNames(); + const ::rtl::OUString* pPropertiesIter = aProperties.getConstArray(); + const ::rtl::OUString* pPropertiesEnd = pPropertiesIter + aProperties.getLength(); + for (;pPropertiesIter != pPropertiesEnd ; ++pPropertiesIter) + { + uno::Any aValue = aPropertiesNode.getNodeValue(*pPropertiesIter + s_sValue); + if ( aValue >>= aStringSeq ) + { + lcl_convert(aStringSeq,aValue); + } + _rValues.put(*pPropertiesIter,aValue); + } // for (;pPropertiesIter != pPropertiesEnd ; ++pPropertiesIter,++pNamedIter) + } // if ( aPropertiesNode.isValid() ) + } + void lcl_readURLPatternNode(const ::utl::OConfigurationTreeRoot& _aInstalled,const ::rtl::OUString& _sEntry,TInstalledDriver& _rInstalledDriver) + { + const ::utl::OConfigurationNode aURLPatternNode = _aInstalled.openNode(_sEntry); + if ( aURLPatternNode.isValid() ) + { + static const ::rtl::OUString s_sParentURLPattern(RTL_CONSTASCII_USTRINGPARAM("ParentURLPattern")); + static const ::rtl::OUString s_sDriver(RTL_CONSTASCII_USTRINGPARAM("Driver")); + static const ::rtl::OUString s_sDriverTypeDisplayName(RTL_CONSTASCII_USTRINGPARAM("DriverTypeDisplayName")); + static const ::rtl::OUString s_sProperties(RTL_CONSTASCII_USTRINGPARAM("Properties")); + static const ::rtl::OUString s_sFeatures(RTL_CONSTASCII_USTRINGPARAM("Features")); + static const ::rtl::OUString s_sMetaData(RTL_CONSTASCII_USTRINGPARAM("MetaData")); + ::rtl::OUString sParentURLPattern; + aURLPatternNode.getNodeValue(s_sParentURLPattern) >>= sParentURLPattern; + if ( sParentURLPattern.getLength() ) + lcl_readURLPatternNode(_aInstalled,sParentURLPattern,_rInstalledDriver); + + ::rtl::OUString sDriverFactory; + aURLPatternNode.getNodeValue(s_sDriver) >>= sDriverFactory; + if ( sDriverFactory.getLength() ) + _rInstalledDriver.sDriverFactory = sDriverFactory; + + ::rtl::OUString sDriverTypeDisplayName; + aURLPatternNode.getNodeValue(s_sDriverTypeDisplayName) >>= sDriverTypeDisplayName; + OSL_ENSURE(sDriverTypeDisplayName.getLength(),"No valid DriverTypeDisplayName property!"); + if ( sDriverTypeDisplayName.getLength() ) + _rInstalledDriver.sDriverTypeDisplayName = sDriverTypeDisplayName; + + lcl_fillValues(aURLPatternNode,s_sProperties,_rInstalledDriver.aProperties); + lcl_fillValues(aURLPatternNode,s_sFeatures,_rInstalledDriver.aFeatures); + lcl_fillValues(aURLPatternNode,s_sMetaData,_rInstalledDriver.aMetaData); + } + } +} +// ----------------------------------------------------------------------------- +DriversConfigImpl::DriversConfigImpl() +{ +} +// ----------------------------------------------------------------------------- +void DriversConfigImpl::Load(const uno::Reference< lang::XMultiServiceFactory >& _rxORB) const +{ + if ( m_aDrivers.empty() ) + { + if ( !m_aInstalled.isValid() ) + { + static const ::rtl::OUString s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.DataAccess.Drivers/Installed")); ///Installed + m_aInstalled = ::utl::OConfigurationTreeRoot::createWithServiceFactory(_rxORB, s_sNodeName, -1, ::utl::OConfigurationTreeRoot::CM_READONLY); + } + + if ( m_aInstalled.isValid() ) + { + const uno::Sequence< ::rtl::OUString > aURLPatterns = m_aInstalled.getNodeNames(); + const ::rtl::OUString* pPatternIter = aURLPatterns.getConstArray(); + const ::rtl::OUString* pPatternEnd = pPatternIter + aURLPatterns.getLength(); + for (;pPatternIter != pPatternEnd ; ++pPatternIter) + { + TInstalledDriver aInstalledDriver; + lcl_readURLPatternNode(m_aInstalled,*pPatternIter,aInstalledDriver); + if ( aInstalledDriver.sDriverFactory.getLength() ) + m_aDrivers.insert(TInstalledDrivers::value_type(*pPatternIter,aInstalledDriver)); + } + } // if ( m_aInstalled.isValid() ) + } +} +// ----------------------------------------------------------------------------- +DriversConfig::DriversConfig(const uno::Reference< lang::XMultiServiceFactory >& _rxORB) +:m_xORB(_rxORB) +{ +} + +// ----------------------------------------------------------------------------- +DriversConfig::~DriversConfig()
+{
+}
+
+// ----------------------------------------------------------------------------- +DriversConfig::DriversConfig( const DriversConfig& _rhs )
+{
+ *this = _rhs;
+}
+
+// ----------------------------------------------------------------------------- +DriversConfig& DriversConfig::operator=( const DriversConfig& _rhs )
+{
+ if ( this != &_rhs )
+ {
+ m_aNode = _rhs.m_aNode;
+ }
+ return *this;
+}
+
+// ----------------------------------------------------------------------------- +::rtl::OUString DriversConfig::getDriverFactoryName(const ::rtl::OUString& _sURL) const +{ + const TInstalledDrivers& rDrivers = m_aNode->getInstalledDrivers(m_xORB); + ::rtl::OUString sRet; + ::rtl::OUString sOldPattern; + TInstalledDrivers::const_iterator aIter = rDrivers.begin(); + TInstalledDrivers::const_iterator aEnd = rDrivers.end(); + for(;aIter != aEnd;++aIter) + { + WildCard aWildCard(aIter->first); + if ( sOldPattern.getLength() < aIter->first.getLength() && aWildCard.Matches(_sURL) ) + { + sRet = aIter->second.sDriverFactory; + sOldPattern = aIter->first; + } + } + + return sRet; +} +// ----------------------------------------------------------------------------- +::rtl::OUString DriversConfig::getDriverTypeDisplayName(const ::rtl::OUString& _sURL) const +{ + const TInstalledDrivers& rDrivers = m_aNode->getInstalledDrivers(m_xORB); + ::rtl::OUString sRet; + ::rtl::OUString sOldPattern; + TInstalledDrivers::const_iterator aIter = rDrivers.begin(); + TInstalledDrivers::const_iterator aEnd = rDrivers.end(); + for(;aIter != aEnd;++aIter) + { + WildCard aWildCard(aIter->first); + if ( sOldPattern.getLength() < aIter->first.getLength() && aWildCard.Matches(_sURL) ) + { + sRet = aIter->second.sDriverTypeDisplayName; + sOldPattern = aIter->first; + } + } + + return sRet; +} +// ----------------------------------------------------------------------------- +const ::comphelper::NamedValueCollection& DriversConfig::getProperties(const ::rtl::OUString& _sURL) const +{ + return impl_get(_sURL,1); +} +// ----------------------------------------------------------------------------- +const ::comphelper::NamedValueCollection& DriversConfig::getFeatures(const ::rtl::OUString& _sURL) const +{ + return impl_get(_sURL,0); +} +// ----------------------------------------------------------------------------- +const ::comphelper::NamedValueCollection& DriversConfig::getMetaData(const ::rtl::OUString& _sURL) const +{ + return impl_get(_sURL,2); +} +// ----------------------------------------------------------------------------- +const ::comphelper::NamedValueCollection& DriversConfig::impl_get(const ::rtl::OUString& _sURL,sal_Int32 _nProps) const +{ + const TInstalledDrivers& rDrivers = m_aNode->getInstalledDrivers(m_xORB); + const ::comphelper::NamedValueCollection* pRet = NULL; + ::rtl::OUString sOldPattern; + TInstalledDrivers::const_iterator aIter = rDrivers.begin(); + TInstalledDrivers::const_iterator aEnd = rDrivers.end(); + for(;aIter != aEnd;++aIter) + { + WildCard aWildCard(aIter->first); + if ( sOldPattern.getLength() < aIter->first.getLength() && aWildCard.Matches(_sURL) ) + { + switch(_nProps) + { + case 0: + pRet = &aIter->second.aFeatures; + break; + case 1: + pRet = &aIter->second.aProperties; + break; + case 2: + pRet = &aIter->second.aMetaData; + break; + } + sOldPattern = aIter->first; + } + } // for(;aIter != aEnd;++aIter) + if ( pRet == NULL ) + { + static const ::comphelper::NamedValueCollection s_sEmpty; + pRet = &s_sEmpty; + } + return *pRet; +} +// ----------------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > DriversConfig::getURLs() const +{ + const TInstalledDrivers& rDrivers = m_aNode->getInstalledDrivers(m_xORB); + uno::Sequence< ::rtl::OUString > aRet(rDrivers.size()); + ::rtl::OUString* pIter = aRet.getArray(); + TInstalledDrivers::const_iterator aIter = rDrivers.begin(); + TInstalledDrivers::const_iterator aEnd = rDrivers.end(); + for(;aIter != aEnd;++aIter,++pIter) + { + *pIter = aIter->first; + } + return aRet; +} diff --git a/connectivity/source/commontools/FDatabaseMetaDataResultSet.cxx b/connectivity/source/commontools/FDatabaseMetaDataResultSet.cxx index 9c3acfb606d5..afa53652d4e6 100644 --- a/connectivity/source/commontools/FDatabaseMetaDataResultSet.cxx +++ b/connectivity/source/commontools/FDatabaseMetaDataResultSet.cxx @@ -133,7 +133,7 @@ void ODatabaseMetaDataResultSet::disposing(void) ::osl::MutexGuard aGuard(m_aMutex); m_aStatement = NULL; - m_xMetaData = NULL; +m_xMetaData.clear(); m_aRowsIter = m_aRows.end(); m_aRows.clear(); m_aRowsIter = m_aRows.end(); diff --git a/connectivity/source/commontools/FValue.cxx b/connectivity/source/commontools/FValue.cxx index a6da2b165612..cd09efa227fe 100644 --- a/connectivity/source/commontools/FValue.cxx +++ b/connectivity/source/commontools/FValue.cxx @@ -35,7 +35,9 @@ #include "connectivity/FValue.hxx" #include "connectivity/CommonTools.hxx" #include <connectivity/dbconversion.hxx> +#include <cppuhelper/extract.hxx> #include <com/sun/star/io/XInputStream.hpp> +#include <rtl/ustrbuf.hxx> #include <rtl/logfile.hxx> using namespace connectivity; @@ -983,12 +985,13 @@ Any ORowSetValue::makeAny() const case DataType::VARBINARY: case DataType::LONGVARBINARY: { - aRet = ::rtl::OUString::createFromAscii("0x"); + ::rtl::OUStringBuffer sVal = ::rtl::OUString::createFromAscii("0x"); Sequence<sal_Int8> aSeq(getSequence()); const sal_Int8* pBegin = aSeq.getConstArray(); const sal_Int8* pEnd = pBegin + aSeq.getLength(); for(;pBegin != pEnd;++pBegin) - aRet += ::rtl::OUString::valueOf((sal_Int32)*pBegin,16); + sVal.append((sal_Int32)*pBegin,16); + aRet = sVal.makeStringAndClear(); } break; case DataType::BIT: @@ -1811,15 +1814,17 @@ void ORowSetValue::fill(sal_Int32 _nPos, sal_Int32 _nType, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow>& _xRow) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::fill" ); + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::fill (1)" ); fill(_nPos,_nType,sal_True,_xRow); } + +// ----------------------------------------------------------------------------- void ORowSetValue::fill(sal_Int32 _nPos, sal_Int32 _nType, sal_Bool _bNullable, const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow>& _xRow) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::fill" ); + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::fill (2)" ); sal_Bool bReadData = sal_True; switch(_nType) { @@ -1888,7 +1893,8 @@ void ORowSetValue::fill(sal_Int32 _nPos, setTypeKind(DataType::BLOB); break; default: - bReadData = sal_False; + OSL_ENSURE( false, "ORowSetValue::fill: unsupported type!" ); + bReadData = false; break; } if ( bReadData && _bNullable && _xRow->wasNull() ) @@ -1898,7 +1904,7 @@ void ORowSetValue::fill(sal_Int32 _nPos, // ----------------------------------------------------------------------------- void ORowSetValue::fill(const Any& _rValue) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::fill" ); + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbtools", "Ocke.Janssen@sun.com", "ORowSetValue::fill (3)" ); switch (_rValue.getValueType().getTypeClass()) { case TypeClass_VOID: @@ -1968,20 +1974,20 @@ void ORowSetValue::fill(const Any& _rValue) setSigned(sal_False); break; } - case TypeClass_HYPER:
- {
- sal_Int64 nValue(0);
- _rValue >>= nValue;
- (*this) = nValue;
- break;
- }
- case TypeClass_UNSIGNED_HYPER:
- {
- sal_uInt64 nValue(0);
- _rValue >>= nValue;
- (*this) = static_cast<sal_Int64>(nValue);
- setSigned(sal_False);
- break;
+ case TypeClass_HYPER: + { + sal_Int64 nValue(0); + _rValue >>= nValue; + (*this) = nValue; + break; + } + case TypeClass_UNSIGNED_HYPER: + { + sal_uInt64 nValue(0); + _rValue >>= nValue; + (*this) = static_cast<sal_Int64>(nValue); + setSigned(sal_False); + break; } case TypeClass_UNSIGNED_LONG: { @@ -1991,11 +1997,44 @@ void ORowSetValue::fill(const Any& _rValue) setSigned(sal_False); break; } + case TypeClass_ENUM: + { + sal_Int32 enumValue( 0 ); + ::cppu::enum2int( enumValue, _rValue ); + (*this) = enumValue; + } + break; + case TypeClass_SEQUENCE: { Sequence<sal_Int8> aDummy; if ( _rValue >>= aDummy ) (*this) = aDummy; + else + OSL_ENSURE( false, "ORowSetValue::fill: unsupported sequence type!" ); + break; + } + + case TypeClass_STRUCT: + { + ::com::sun::star::util::Date aDate; + ::com::sun::star::util::Time aTime; + ::com::sun::star::util::DateTime aDateTime; + if ( _rValue >>= aDate ) + { + (*this) = aDate; + } + else if ( _rValue >>= aTime ) + { + (*this) = aTime; + } + else if ( _rValue >>= aDateTime ) + { + (*this) = aDateTime; + } + else + OSL_ENSURE( false, "ORowSetValue::fill: unsupported structure!" ); + break; } diff --git a/connectivity/source/commontools/RowFunctionParser.cxx b/connectivity/source/commontools/RowFunctionParser.cxx index 541df8e6b2cc..15221ed0e260 100644 --- a/connectivity/source/commontools/RowFunctionParser.cxx +++ b/connectivity/source/commontools/RowFunctionParser.cxx @@ -40,7 +40,7 @@ #include <typeinfo> #define BOOST_SPIRIT_DEBUG #endif -#include <boost/spirit/core.hpp> +#include <boost/spirit/include/classic_core.hpp> #include "RowFunctionParser.hxx" #include <rtl/ustring.hxx> #include <tools/fract.hxx> diff --git a/connectivity/source/commontools/TColumnsHelper.cxx b/connectivity/source/commontools/TColumnsHelper.cxx index 2ce570e95936..8d02cfccab4a 100644 --- a/connectivity/source/commontools/TColumnsHelper.cxx +++ b/connectivity/source/commontools/TColumnsHelper.cxx @@ -37,6 +37,9 @@ #include <com/sun/star/sdbc/XResultSet.hpp> #include <com/sun/star/sdbc/DataType.hpp> #include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbcx/KeyType.hpp> +#include <com/sun/star/sdbcx/XColumnsSupplier.hpp> +#include <com/sun/star/sdbcx/XKeysSupplier.hpp> #include <comphelper/types.hxx> #include "connectivity/dbtools.hxx" #include "TConnection.hxx" @@ -51,7 +54,7 @@ using namespace connectivity; using namespace dbtools; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::beans; -// using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::sdbcx; using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::container; using namespace ::com::sun::star::lang; @@ -114,17 +117,67 @@ sdbcx::ObjectType OColumnsHelper::createObject(const ::rtl::OUString& _rName) bAutoIncrement = aFind->second.first.first; bIsCurrency = aFind->second.first.second; nDataType = aFind->second.second; - } + } // if ( aFind != m_pImpl->m_aColumnInfo.end() ) + sdbcx::ObjectType xRet; + const ColumnDesc* pColDesc = m_pTable->getColumnDescription(_rName); + if ( pColDesc ) + { + Reference<XPropertySet> xPr = m_pTable; + Reference<XKeysSupplier> xKeysSup(xPr,UNO_QUERY); + Reference<XNameAccess> xPrimaryKeyColumns; + if ( xKeysSup.is() ) + { + const Reference<XIndexAccess> xKeys = xKeysSup->getKeys(); + if ( xKeys.is() ) + { + ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); + const sal_Int32 nKeyCount = xKeys->getCount(); + for(sal_Int32 nKeyIter = 0; nKeyIter < nKeyCount;++nKeyIter) + { + const Reference<XPropertySet> xKey(xKeys->getByIndex(nKeyIter),UNO_QUERY_THROW); + sal_Int32 nType = 0; + xKey->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE)) >>= nType; + if ( nType == KeyType::PRIMARY ) + { + const Reference<XColumnsSupplier> xColS(xKey,UNO_QUERY_THROW); + xPrimaryKeyColumns = xColS->getColumns(); + break; + } + } // for(sal_Int32 nKeyIter = 0; nKeyIter < nKeyCount;++) + } + } + sal_Int32 nField11 = pColDesc->nField11; + if ( nField11 != ColumnValue::NO_NULLS && xPrimaryKeyColumns.is() && xPrimaryKeyColumns->hasByName(_rName) ) + { + nField11 = ColumnValue::NO_NULLS; + } // if ( xKeys.is() ) + connectivity::sdbcx::OColumn* pRet = new connectivity::sdbcx::OColumn(_rName, + pColDesc->aField6, + pColDesc->sField13, + nField11, + pColDesc->nField7, + pColDesc->nField9, + pColDesc->nField5, + bAutoIncrement, + sal_False, + bIsCurrency, + isCaseSensitive()); + + xRet = pRet; + } + else + { - sdbcx::ObjectType xRet(::dbtools::createSDBCXColumn( m_pTable, - xConnection, - _rName, - isCaseSensitive(), - bQueryInfo, - bAutoIncrement, - bIsCurrency, - nDataType),UNO_QUERY); + xRet.set(::dbtools::createSDBCXColumn( m_pTable, + xConnection, + _rName, + isCaseSensitive(), + bQueryInfo, + bAutoIncrement, + bIsCurrency, + nDataType),UNO_QUERY); + } return xRet; } diff --git a/connectivity/source/commontools/TDatabaseMetaDataBase.cxx b/connectivity/source/commontools/TDatabaseMetaDataBase.cxx index 5f5aaabe5c72..b3cbb4ae67c7 100644 --- a/connectivity/source/commontools/TDatabaseMetaDataBase.cxx +++ b/connectivity/source/commontools/TDatabaseMetaDataBase.cxx @@ -90,8 +90,8 @@ Sequence< PropertyValue > SAL_CALL ODatabaseMetaDataBase::getConnectionInfo( ) void SAL_CALL ODatabaseMetaDataBase::disposing( const EventObject& /*Source*/ ) throw(RuntimeException) { // cut off all references to the connection - m_xConnection = NULL; - m_xListenerHelper = NULL; +m_xConnection.clear(); +m_xListenerHelper.clear(); } // ----------------------------------------------------------------------------- Reference< XResultSet > SAL_CALL ODatabaseMetaDataBase::getTypeInfo( ) throw(SQLException, RuntimeException) diff --git a/connectivity/source/commontools/TIndexColumns.cxx b/connectivity/source/commontools/TIndexColumns.cxx index 00a153ceeed0..89fa282f2e74 100644 --- a/connectivity/source/commontools/TIndexColumns.cxx +++ b/connectivity/source/commontools/TIndexColumns.cxx @@ -85,7 +85,7 @@ sdbcx::ObjectType OIndexColumns::createObject(const ::rtl::OUString& _rName) m_pIndex->getTable()->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)), aSchema,aTable,_rName); - sdbcx::ObjectType xRet = NULL; + sdbcx::ObjectType xRet; if ( xResult.is() ) { Reference< XRow > xRow(xResult,UNO_QUERY); diff --git a/connectivity/source/commontools/TIndexes.cxx b/connectivity/source/commontools/TIndexes.cxx index 3257f8c984c0..cf17b7a51411 100644 --- a/connectivity/source/commontools/TIndexes.cxx +++ b/connectivity/source/commontools/TIndexes.cxx @@ -97,8 +97,8 @@ sdbcx::ObjectType OIndexesHelper::createObject(const ::rtl::OUString& _rName) { sal_Int32 nClustered = xRow->getShort(7); sal_Bool bPrimarKeyIndex = sal_False; - xRow = NULL; - xResult = NULL; + xRow.clear(); + xResult.clear(); try { xResult = m_pTable->getMetaData()->getPrimaryKeys(aCatalog,aSchema,aTable); diff --git a/connectivity/source/commontools/TKey.cxx b/connectivity/source/commontools/TKey.cxx index c065e11cf24c..1218c752ec50 100644 --- a/connectivity/source/commontools/TKey.cxx +++ b/connectivity/source/commontools/TKey.cxx @@ -71,38 +71,43 @@ void OTableKeyHelper::refreshColumns() ::std::vector< ::rtl::OUString> aVector; if ( !isNew() ) { - ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); - ::rtl::OUString aSchema,aTable; - m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema; - m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable; - - if ( m_Name.getLength() ) // foreign key + aVector = m_aProps->m_aKeyColumnNames; + if ( aVector.empty() ) { + ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); + ::rtl::OUString aSchema,aTable; + m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema; + m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable; - Reference< XResultSet > xResult = m_pTable->getMetaData()->getImportedKeys(m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)), - aSchema,aTable); - - if ( xResult.is() ) + if ( m_Name.getLength() ) // foreign key { - Reference< XRow > xRow(xResult,UNO_QUERY); - while( xResult->next() ) + + Reference< XResultSet > xResult = m_pTable->getMetaData()->getImportedKeys(m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)), + aSchema,aTable); + + if ( xResult.is() ) { - ::rtl::OUString aForeignKeyColumn = xRow->getString(8); - if(xRow->getString(12) == m_Name) - aVector.push_back(aForeignKeyColumn); + Reference< XRow > xRow(xResult,UNO_QUERY); + while( xResult->next() ) + { + ::rtl::OUString aForeignKeyColumn = xRow->getString(8); + if(xRow->getString(12) == m_Name) + aVector.push_back(aForeignKeyColumn); + } } } - } - if ( aVector.empty() ) - { - Reference< XResultSet > xResult = m_pTable->getMetaData()->getPrimaryKeys(m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)), - aSchema,aTable); - if ( xResult.is() ) + if ( aVector.empty() ) { - Reference< XRow > xRow(xResult,UNO_QUERY); - while( xResult->next() ) - aVector.push_back(xRow->getString(4)); + const Reference< XResultSet > xResult = m_pTable->getMetaData()->getPrimaryKeys(m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)), + aSchema,aTable); + + if ( xResult.is() ) + { + const Reference< XRow > xRow(xResult,UNO_QUERY); + while( xResult->next() ) + aVector.push_back(xRow->getString(4)); + } // if ( xResult.is() ) } } } diff --git a/connectivity/source/commontools/TPrivilegesResultSet.cxx b/connectivity/source/commontools/TPrivilegesResultSet.cxx index 0de0c1e077b5..509d924779de 100644 --- a/connectivity/source/commontools/TPrivilegesResultSet.cxx +++ b/connectivity/source/commontools/TPrivilegesResultSet.cxx @@ -127,8 +127,8 @@ const ORowSetValue& OResultSetPrivileges::getValue(sal_Int32 columnIndex) void SAL_CALL OResultSetPrivileges::disposing(void) { ODatabaseMetaDataResultSet::disposing(); - m_xTables = NULL; - m_xRow = NULL; +m_xTables.clear(); +m_xRow.clear(); } // ----------------------------------------------------------------------------- sal_Bool SAL_CALL OResultSetPrivileges::next( ) throw(SQLException, RuntimeException) diff --git a/connectivity/source/commontools/TTableHelper.cxx b/connectivity/source/commontools/TTableHelper.cxx index ecec91aa6f32..477ec01c0499 100644 --- a/connectivity/source/commontools/TTableHelper.cxx +++ b/connectivity/source/commontools/TTableHelper.cxx @@ -38,6 +38,7 @@ #include <cppuhelper/typeprovider.hxx> #include <com/sun/star/lang/DisposedException.hpp> #include <com/sun/star/sdbc/ColumnValue.hpp> +#include <comphelper/implementationreference.hxx> #include <comphelper/sequence.hxx> #include <comphelper/extract.hxx> #include <comphelper/types.hxx> @@ -54,16 +55,70 @@ using namespace ::com::sun::star::sdbcx; using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::container; using namespace ::com::sun::star::lang; +namespace +{ + /// helper class for column property change events which holds the OComponentDefinition weak +typedef ::cppu::WeakImplHelper1 < XContainerListener > OTableContainerListener_BASE; +class OTableContainerListener : public OTableContainerListener_BASE +{ + OTableHelper* m_pComponent; + ::std::map< ::rtl::OUString,bool> m_aRefNames; + + OTableContainerListener(const OTableContainerListener&); + void operator =(const OTableContainerListener&); +protected: + virtual ~OTableContainerListener(){} +public: + OTableContainerListener(OTableHelper* _pComponent) : m_pComponent(_pComponent){} + virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& /*Event*/ ) throw (RuntimeException) + { + } + virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) throw (RuntimeException) + { + ::rtl::OUString sName; + Event.Accessor >>= sName; + if ( m_aRefNames.find(sName) != m_aRefNames.end() ) + m_pComponent->refreshKeys(); + } + virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event ) throw (RuntimeException) + { + ::rtl::OUString sOldComposedName,sNewComposedName; + Event.ReplacedElement >>= sOldComposedName; + Event.Accessor >>= sNewComposedName; + if ( sOldComposedName != sNewComposedName && m_aRefNames.find(sOldComposedName) != m_aRefNames.end() ) + m_pComponent->refreshKeys(); + } + // XEventListener + virtual void SAL_CALL disposing( const EventObject& /*_rSource*/ ) throw (RuntimeException) + { + } + void clear() { m_pComponent = NULL; } + inline void add(const ::rtl::OUString& _sRefName) { m_aRefNames.insert(::std::map< ::rtl::OUString,bool>::value_type(_sRefName,true)); } +}; +} +namespace connectivity +{ + struct OTableHelperImpl + { + TKeyMap m_aKeys; + Reference< ::com::sun::star::sdbc::XDatabaseMetaData > m_xMetaData; + Reference< ::com::sun::star::sdbc::XConnection > m_xConnection; + ::comphelper::ImplementationReference< OTableContainerListener,XContainerListener> + m_xTablePropertyListener; + ::std::vector< ColumnDesc > m_aColumnDesc; + }; +} OTableHelper::OTableHelper( sdbcx::OCollection* _pTables, const Reference< XConnection >& _xConnection, sal_Bool _bCase) :OTable_TYPEDEF(_pTables,_bCase) - ,m_xConnection(_xConnection) + ,m_pImpl(new OTableHelperImpl) { try { - m_xMetaData = m_xConnection->getMetaData(); + m_pImpl->m_xConnection = _xConnection; + m_pImpl->m_xMetaData = m_pImpl->m_xConnection->getMetaData(); } catch(const Exception&) { @@ -85,42 +140,41 @@ OTableHelper::OTableHelper( sdbcx::OCollection* _pTables, _Description, _SchemaName, _CatalogName) - ,m_xConnection(_xConnection) + ,m_pImpl(new OTableHelperImpl) { try { - m_xMetaData = m_xConnection->getMetaData(); + m_pImpl->m_xConnection = _xConnection; + m_pImpl->m_xMetaData = m_pImpl->m_xConnection->getMetaData(); } catch(const Exception&) { } } // ----------------------------------------------------------------------------- +OTableHelper::~OTableHelper() +{ +} +// ----------------------------------------------------------------------------- void SAL_CALL OTableHelper::disposing() { - OTable_TYPEDEF::disposing(); ::osl::MutexGuard aGuard(m_aMutex); - m_xConnection = NULL; - m_xMetaData = NULL; + if ( m_pImpl->m_xTablePropertyListener.is() ) + { + m_pTables->removeContainerListener(m_pImpl->m_xTablePropertyListener.getRef()); + m_pImpl->m_xTablePropertyListener->clear(); + m_pImpl->m_xTablePropertyListener.dispose(); + } + OTable_TYPEDEF::disposing(); + + m_pImpl->m_xConnection = NULL; + m_pImpl->m_xMetaData = NULL; + } // ------------------------------------------------------------------------- namespace { - typedef sal_Int32 OrdinalPosition; - struct ColumnDesc - { - ::rtl::OUString sName; - OrdinalPosition nOrdinalPosition; - - ColumnDesc() {} - ColumnDesc( const ::rtl::OUString& _rName, OrdinalPosition _nPosition ) - :sName( _rName ) - ,nOrdinalPosition( _nPosition ) - { - } - }; - /** collects ColumnDesc's from a resultset produced by XDatabaseMetaData::getColumns */ void lcl_collectColumnDescs_throw( const Reference< XResultSet >& _rxResult, ::std::vector< ColumnDesc >& _out_rColumns ) @@ -131,8 +185,14 @@ namespace while ( _rxResult->next() ) { sName = xRow->getString( 4 ); // COLUMN_NAME + sal_Int32 nField5 = xRow->getInt(5); + ::rtl::OUString aField6 = xRow->getString(6); + sal_Int32 nField7 = xRow->getInt(7) + , nField9 = xRow->getInt(9) + , nField11= xRow->getInt(11); + ::rtl::OUString sField13 = xRow->getString(13); nOrdinalPosition = xRow->getInt( 17 ); // ORDINAL_POSITION - _out_rColumns.push_back( ColumnDesc( sName, nOrdinalPosition ) ); + _out_rColumns.push_back( ColumnDesc( sName,nField5,aField6,nField7,nField9,nField11,sField13, nOrdinalPosition ) ); } } @@ -201,16 +261,16 @@ void OTableHelper::refreshColumns() ) ); // collect the column names, together with their ordinal position - ::std::vector< ColumnDesc > aColumns; - lcl_collectColumnDescs_throw( xResult, aColumns ); + m_pImpl->m_aColumnDesc.clear(); + lcl_collectColumnDescs_throw( xResult, m_pImpl->m_aColumnDesc ); // ensure that the ordinal positions as obtained from the meta data do make sense - lcl_sanitizeColumnDescs( aColumns ); + lcl_sanitizeColumnDescs( m_pImpl->m_aColumnDesc ); // sort by ordinal position ::std::map< OrdinalPosition, ::rtl::OUString > aSortedColumns; - for ( ::std::vector< ColumnDesc >::const_iterator copy = aColumns.begin(); - copy != aColumns.end(); + for ( ::std::vector< ColumnDesc >::const_iterator copy = m_pImpl->m_aColumnDesc.begin(); + copy != m_pImpl->m_aColumnDesc.end(); ++copy ) aSortedColumns[ copy->nOrdinalPosition ] = copy->sName; @@ -229,6 +289,21 @@ void OTableHelper::refreshColumns() else m_pColumns = createColumns(aVector); } +// ----------------------------------------------------------------------------- +const ColumnDesc* OTableHelper::getColumnDescription(const ::rtl::OUString& _sName) const +{ + const ColumnDesc* pRet = NULL; + ::std::vector< ColumnDesc >::const_iterator aEnd = m_pImpl->m_aColumnDesc.end(); + for (::std::vector< ColumnDesc >::const_iterator aIter = m_pImpl->m_aColumnDesc.begin();aIter != aEnd;++aIter) + { + if ( aIter->sName == _sName ) + { + pRet = &*aIter; + break; + } + } // for (::std::vector< ColumnDesc >::const_iterator aIter = m_pImpl->m_aColumnDesc.begin();aIter != aEnd;++aIter) + return pRet; +} // ------------------------------------------------------------------------- void OTableHelper::refreshPrimaryKeys(TStringVector& _rNames) { @@ -237,14 +312,26 @@ void OTableHelper::refreshPrimaryKeys(TStringVector& _rNames) aCatalog <<= m_CatalogName; Reference< XResultSet > xResult = getMetaData()->getPrimaryKeys(aCatalog,m_SchemaName,m_Name); - if ( xResult.is() && xResult->next() ) + if ( xResult.is() ) { - Reference< XRow > xRow(xResult,UNO_QUERY); - const ::rtl::OUString aPkName = xRow->getString(6); - m_aKeys.insert(TKeyMap::value_type(aPkName,sdbcx::TKeyProperties(new sdbcx::KeyProperties(::rtl::OUString(),KeyType::PRIMARY,0,0)))); + sdbcx::TKeyProperties pKeyProps(new sdbcx::KeyProperties(::rtl::OUString(),KeyType::PRIMARY,0,0)); + ::rtl::OUString aPkName; + bool bAlreadyFetched = false; + const Reference< XRow > xRow(xResult,UNO_QUERY); + while ( xResult->next() ) + { + pKeyProps->m_aKeyColumnNames.push_back(xRow->getString(4)); + if ( !bAlreadyFetched ) + { + aPkName = xRow->getString(6); + bAlreadyFetched = true; + } + } + + m_pImpl->m_aKeys.insert(TKeyMap::value_type(aPkName,pKeyProps)); _rNames.push_back(aPkName); - ::comphelper::disposeComponent(xResult); - } + } // if ( xResult.is() && xResult->next() ) + ::comphelper::disposeComponent(xResult); } // ------------------------------------------------------------------------- void OTableHelper::refreshForgeinKeys(TStringVector& _rNames) @@ -257,7 +344,8 @@ void OTableHelper::refreshForgeinKeys(TStringVector& _rNames) if ( xRow.is() ) { - ::rtl::OUString aName,sCatalog,aSchema; + sdbcx::TKeyProperties pKeyProps; + ::rtl::OUString aName,sCatalog,aSchema,sOldFKName; while( xResult->next() ) { // this must be outsid the "if" because we have to call in a right order @@ -267,29 +355,51 @@ void OTableHelper::refreshForgeinKeys(TStringVector& _rNames) aSchema = xRow->getString(2); aName = xRow->getString(3); - const sal_Int32 nKeySeq = xRow->getInt(9); + const ::rtl::OUString sForeignKeyColumn = xRow->getString(8); const sal_Int32 nUpdateRule = xRow->getInt(10); const sal_Int32 nDeleteRule = xRow->getInt(11); + const ::rtl::OUString sFkName = xRow->getString(12); + + if ( pKeyProps.get() ) + { + } + - if ( nKeySeq == 1 ) - { // only append when the sequnce number is 1 to forbid serveral inserting the same key name - const ::rtl::OUString sFkName = xRow->getString(12); - if ( sFkName.getLength() && !xRow->wasNull() ) + if ( sFkName.getLength() && !xRow->wasNull() ) + { + if ( sOldFKName != sFkName ) { - ::rtl::OUString sReferencedName; - sReferencedName = ::dbtools::composeTableName(getMetaData(),sCatalog,aSchema,aName,sal_False,::dbtools::eInDataManipulation); - m_aKeys.insert(TKeyMap::value_type(sFkName,sdbcx::TKeyProperties(new sdbcx::KeyProperties(sReferencedName,KeyType::FOREIGN,nUpdateRule,nDeleteRule)))); + if ( pKeyProps.get() ) + m_pImpl->m_aKeys.insert(TKeyMap::value_type(sOldFKName,pKeyProps)); + + const ::rtl::OUString sReferencedName = ::dbtools::composeTableName(getMetaData(),sCatalog,aSchema,aName,sal_False,::dbtools::eInDataManipulation); + pKeyProps.reset(new sdbcx::KeyProperties(sReferencedName,KeyType::FOREIGN,nUpdateRule,nDeleteRule)); + pKeyProps->m_aKeyColumnNames.push_back(sForeignKeyColumn); _rNames.push_back(sFkName); + if ( m_pTables->hasByName(sReferencedName) ) + { + if ( !m_pImpl->m_xTablePropertyListener.is() ) + m_pImpl->m_xTablePropertyListener = ::comphelper::ImplementationReference< OTableContainerListener,XContainerListener>( new OTableContainerListener(this) ); + m_pTables->addContainerListener(m_pImpl->m_xTablePropertyListener.getRef()); + m_pImpl->m_xTablePropertyListener->add(sReferencedName); + } // if ( m_pTables->hasByName(sReferencedName) ) + sOldFKName = sFkName; + } // if ( sOldFKName != sFkName ) + else if ( pKeyProps.get() ) + { + pKeyProps->m_aKeyColumnNames.push_back(sForeignKeyColumn); } } - } + } // while( xResult->next() ) + if ( pKeyProps.get() ) + m_pImpl->m_aKeys.insert(TKeyMap::value_type(sOldFKName,pKeyProps)); ::comphelper::disposeComponent(xResult); } } // ------------------------------------------------------------------------- void OTableHelper::refreshKeys() { - m_aKeys.clear(); + m_pImpl->m_aKeys.clear(); TStringVector aNames; @@ -386,7 +496,7 @@ void SAL_CALL OTableHelper::rename( const ::rtl::OUString& newName ) throw(SQLEx sComposedName = ::dbtools::composeTableName(getMetaData(),sCatalog,sSchema,sTable,sal_True,::dbtools::eInDataManipulation); sSql += sComposedName; - Reference< XStatement > xStmt = m_xConnection->createStatement( ); + Reference< XStatement > xStmt = m_pImpl->m_xConnection->createStatement( ); if ( xStmt.is() ) { xStmt->execute(sSql); @@ -401,7 +511,7 @@ void SAL_CALL OTableHelper::rename( const ::rtl::OUString& newName ) throw(SQLEx // ----------------------------------------------------------------------------- Reference< XDatabaseMetaData> OTableHelper::getMetaData() const { - return m_xMetaData; + return m_pImpl->m_xMetaData; } // ------------------------------------------------------------------------- void SAL_CALL OTableHelper::alterColumnByIndex( sal_Int32 index, const Reference< XPropertySet >& descriptor ) throw(SQLException, ::com::sun::star::lang::IndexOutOfBoundsException, RuntimeException) @@ -441,8 +551,8 @@ void SAL_CALL OTableHelper::release() throw() sdbcx::TKeyProperties OTableHelper::getKeyProperties(const ::rtl::OUString& _sName) const { sdbcx::TKeyProperties pKeyProps; - TKeyMap::const_iterator aFind = m_aKeys.find(_sName); - if ( aFind != m_aKeys.end() ) + TKeyMap::const_iterator aFind = m_pImpl->m_aKeys.find(_sName); + if ( aFind != m_pImpl->m_aKeys.end() ) { pKeyProps = aFind->second; } @@ -457,7 +567,7 @@ sdbcx::TKeyProperties OTableHelper::getKeyProperties(const ::rtl::OUString& _sNa // ----------------------------------------------------------------------------- void OTableHelper::addKey(const ::rtl::OUString& _sName,const sdbcx::TKeyProperties& _aKeyProperties) { - m_aKeys.insert(TKeyMap::value_type(_sName,_aKeyProperties)); + m_pImpl->m_aKeys.insert(TKeyMap::value_type(_sName,_aKeyProperties)); } // ----------------------------------------------------------------------------- ::rtl::OUString OTableHelper::getTypeCreatePattern() const @@ -465,4 +575,7 @@ void OTableHelper::addKey(const ::rtl::OUString& _sName,const sdbcx::TKeyPropert return ::rtl::OUString(); } // ----------------------------------------------------------------------------- - +Reference< XConnection> OTableHelper::getConnection() const +{ + return m_pImpl->m_xConnection; +} diff --git a/connectivity/source/commontools/dbconversion.cxx b/connectivity/source/commontools/dbconversion.cxx index 995c5323bc89..2d620018c73f 100644 --- a/connectivity/source/commontools/dbconversion.cxx +++ b/connectivity/source/commontools/dbconversion.cxx @@ -40,7 +40,7 @@ #include <com/sun/star/util/Date.hpp> #include <com/sun/star/util/Time.hpp> #include <com/sun/star/util/DateTime.hpp> - +#include <rtl/ustrbuf.hxx> #define MAX_DAYS 3636532 @@ -96,13 +96,13 @@ namespace dbtools ::rtl::OUString DBTypeConversion::toDateTimeString(const DateTime& _rDateTime) { Date aDate(_rDateTime.Day,_rDateTime.Month,_rDateTime.Year); - ::rtl::OUString aTemp(toDateString(aDate)); - aTemp += ::rtl::OUString::createFromAscii(" "); + ::rtl::OUStringBuffer aTemp(toDateString(aDate)); + aTemp.appendAscii(" "); Time aTime(0,_rDateTime.Seconds,_rDateTime.Minutes,_rDateTime.Hours); - aTemp += toTimeString(aTime); - aTemp += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".")); - aTemp += ::rtl::OUString::valueOf(static_cast<sal_Int32>(_rDateTime.HundredthSeconds)); - return aTemp; + aTemp.append( toTimeString(aTime) ); + aTemp.appendAscii("."); + aTemp.append( static_cast<sal_Int32>(_rDateTime.HundredthSeconds)); + return aTemp.makeStringAndClear(); } //------------------------------------------------------------------------------ Date DBTypeConversion::toDate(sal_Int32 _nVal) diff --git a/connectivity/source/commontools/dbmetadata.cxx b/connectivity/source/commontools/dbmetadata.cxx index c68fed6905ce..c5b65a9d113b 100644 --- a/connectivity/source/commontools/dbmetadata.cxx +++ b/connectivity/source/commontools/dbmetadata.cxx @@ -31,8 +31,9 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_connectivity.hxx" -#include <connectivity/dbmetadata.hxx> -#include <connectivity/dbexception.hxx> +#include "connectivity/dbmetadata.hxx" +#include "connectivity/dbexception.hxx" +#include "connectivity/DriversConfig.hxx" #include "resource/common_res.hrc" #include "resource/sharedresources.hxx" @@ -52,6 +53,7 @@ #include <tools/diagnose_ex.h> #include <comphelper/namedvaluecollection.hxx> #include <comphelper/componentcontext.hxx> +#include <comphelper/processfactory.hxx> #include <boost/optional.hpp> @@ -90,9 +92,19 @@ namespace dbtools { Reference< XConnection > xConnection; Reference< XDatabaseMetaData > xConnectionMetaData; + ::connectivity::DriversConfig aDriverConfig; ::boost::optional< ::rtl::OUString > sCachedIdentifierQuoteString; ::boost::optional< ::rtl::OUString > sCachedCatalogSeparator; + + DatabaseMetaData_Impl() + :xConnection() + ,xConnectionMetaData() + ,aDriverConfig( ::comphelper::getProcessServiceFactory() ) + ,sCachedIdentifierQuoteString() + ,sCachedCatalogSeparator() + { + } }; //-------------------------------------------------------------------- @@ -122,6 +134,17 @@ namespace dbtools } //................................................................ + static bool lcl_getDriverSetting( const sal_Char* _asciiName, const DatabaseMetaData_Impl& _metaData, Any& _out_setting ) + { + lcl_checkConnected( _metaData ); + const ::comphelper::NamedValueCollection& rDriverMetaData = _metaData.aDriverConfig.getMetaData( _metaData.xConnectionMetaData->getURL() ); + if ( !rDriverMetaData.has( _asciiName ) ) + return false; + _out_setting = rDriverMetaData.get( _asciiName ); + return true; + } + + //................................................................ static bool lcl_getConnectionSetting( const sal_Char* _asciiName, const DatabaseMetaData_Impl& _metaData, Any& _out_setting ) { try @@ -157,10 +180,9 @@ namespace dbtools const DatabaseMetaData_Impl& _metaData, ::boost::optional< ::rtl::OUString >& _cachedSetting, ::rtl::OUString (SAL_CALL XDatabaseMetaData::*_getter)() ) { - lcl_checkConnected( _metaData ); - if ( !_cachedSetting ) { + lcl_checkConnected( _metaData ); try { _cachedSetting.reset( (_metaData.xConnectionMetaData.get()->*_getter)() ); @@ -276,7 +298,15 @@ namespace dbtools OSL_VERIFY( setting >>= doGenerate ); return doGenerate; } - + //-------------------------------------------------------------------- + bool DatabaseMetaData::isAutoIncrementPrimaryKey() const + { + bool is( true ); + Any setting; + if ( lcl_getDriverSetting( "AutoIncrementIsPrimaryKey", *m_pImpl, setting ) ) + OSL_VERIFY( setting >>= is ); + return is; + } //-------------------------------------------------------------------- sal_Int32 DatabaseMetaData::getBooleanComparisonMode() const { @@ -297,6 +327,7 @@ namespace dbtools } catch( const Exception& ) { + DBG_UNHANDLED_EXCEPTION(); } try { @@ -376,6 +407,22 @@ namespace dbtools #endif return doDisplay; } + //-------------------------------------------------------------------- + bool DatabaseMetaData::supportsThreads() const + { + bool bSupported( true ); + try + { + Reference< XDatabaseMetaData > xMeta( m_pImpl->xConnectionMetaData, UNO_SET_THROW ); + ::rtl::OUString sConnectionURL( xMeta->getURL() ); + bSupported = sConnectionURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "sdbc:mysql:mysqlc" ) ) != 0; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return bSupported; + } //........................................................................ } // namespace dbtools diff --git a/connectivity/source/commontools/dbtools.cxx b/connectivity/source/commontools/dbtools.cxx index a1847c98d2ab..02e6e420142f 100644 --- a/connectivity/source/commontools/dbtools.cxx +++ b/connectivity/source/commontools/dbtools.cxx @@ -842,9 +842,8 @@ static ::rtl::OUString impl_doComposeTableName( const Reference< XDatabaseMetaDa return ::rtl::OUString(); OSL_ENSURE(_rName.getLength(), "impl_doComposeTableName : at least the name should be non-empty !"); - ::rtl::OUString sQuoteString = _rxMetaData->getIdentifierQuoteString(); - - NameComponentSupport aNameComps( lcl_getNameComponentSupport( _rxMetaData, _eComposeRule ) ); + const ::rtl::OUString sQuoteString = _rxMetaData->getIdentifierQuoteString(); + const NameComponentSupport aNameComps( lcl_getNameComponentSupport( _rxMetaData, _eComposeRule ) ); ::rtl::OUStringBuffer aComposedName; @@ -1014,7 +1013,6 @@ try Property* pResult = ::std::lower_bound(pNewProps, pNewProps + nNewLen,pOldProps[i].Name, ::comphelper::PropertyStringLessFunctor()); if ( pResult && ( pResult != pNewProps + nNewLen && pResult->Name == pOldProps[i].Name ) - && ( pResult->Attributes == pOldProps[i].Attributes ) && ( (pResult->Attributes & PropertyAttribute::READONLY) == 0 ) && ( pResult->Type.equals(pOldProps[i].Type)) ) { // Attribute stimmen ueberein und Property ist nicht read-only @@ -1711,13 +1709,63 @@ sal_Bool implSetObject( const Reference< XParameters >& _rxParameters, } //.................................................................. - +namespace +{ + class OParameterWrapper : public ::cppu::WeakImplHelper1< XIndexAccess > + { + ::std::bit_vector m_aSet; + Reference<XIndexAccess> m_xSource; + public: + OParameterWrapper(const ::std::bit_vector& _aSet,const Reference<XIndexAccess>& _xSource) : m_aSet(_aSet),m_xSource(_xSource){} + private: + // ::com::sun::star::container::XElementAccess + virtual Type SAL_CALL getElementType() throw(RuntimeException) + { + return m_xSource->getElementType(); + } + virtual sal_Bool SAL_CALL hasElements( ) throw(RuntimeException) + { + if ( m_aSet.empty() ) + return m_xSource->hasElements(); + return ::std::count(m_aSet.begin(),m_aSet.end(),false) != 0; + } + // ::com::sun::star::container::XIndexAccess + virtual sal_Int32 SAL_CALL getCount( ) throw(RuntimeException) + { + if ( m_aSet.empty() ) + return m_xSource->getCount(); + return ::std::count(m_aSet.begin(),m_aSet.end(),false); + } + virtual Any SAL_CALL getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException) + { + if ( m_aSet.empty() ) + return m_xSource->getByIndex(Index); + if ( m_aSet.size() < (size_t)Index ) + throw IndexOutOfBoundsException(); + + ::std::bit_vector::iterator aIter = m_aSet.begin(); + ::std::bit_vector::iterator aEnd = m_aSet.end(); + sal_Int32 i = 0; + sal_Int32 nParamPos = -1; + for(; aIter != aEnd && i <= Index; ++aIter) + { + ++nParamPos; + if ( !*aIter ) + { + ++i; + } + } + return m_xSource->getByIndex(nParamPos); + } + }; +} // ----------------------------------------------------------------------------- void askForParameters(const Reference< XSingleSelectQueryComposer >& _xComposer, const Reference<XParameters>& _xParameters, const Reference< XConnection>& _xConnection, - const Reference< XInteractionHandler >& _rxHandler) + const Reference< XInteractionHandler >& _rxHandler, + const ::std::bit_vector& _aParametersSet) { OSL_ENSURE(_xComposer.is(),"dbtools::askForParameters XSQLQueryComposer is null!"); OSL_ENSURE(_xParameters.is(),"dbtools::askForParameters XParameters is null!"); @@ -1730,7 +1778,7 @@ void askForParameters(const Reference< XSingleSelectQueryComposer >& _xComposer, Reference<XIndexAccess> xParamsAsIndicies = xParameters.is() ? xParameters->getParameters() : Reference<XIndexAccess>(); Reference<XNameAccess> xParamsAsNames(xParamsAsIndicies, UNO_QUERY); sal_Int32 nParamCount = xParamsAsIndicies.is() ? xParamsAsIndicies->getCount() : 0; - if (nParamCount) + if ( (nParamCount && _aParametersSet.empty()) || ::std::count(_aParametersSet.begin(),_aParametersSet.end(),true) != nParamCount ) { // build an interaction request // two continuations (Ok and Cancel) @@ -1738,7 +1786,8 @@ void askForParameters(const Reference< XSingleSelectQueryComposer >& _xComposer, OParameterContinuation* pParams = new OParameterContinuation; // the request ParametersRequest aRequest; - aRequest.Parameters = xParamsAsIndicies; + Reference<XIndexAccess> xWrappedParameters = new OParameterWrapper(_aParametersSet,xParamsAsIndicies); + aRequest.Parameters = xWrappedParameters; aRequest.Connection = _xConnection; OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest)); Reference< XInteractionRequest > xRequest(pRequest); @@ -1762,8 +1811,7 @@ void askForParameters(const Reference< XSingleSelectQueryComposer >& _xComposer, const PropertyValue* pFinalValues = aFinalValues.getConstArray(); for (sal_Int32 i=0; i<aFinalValues.getLength(); ++i, ++pFinalValues) { - Reference< XPropertySet > xParamColumn; - ::cppu::extractInterface(xParamColumn, xParamsAsIndicies->getByIndex(i)); + Reference< XPropertySet > xParamColumn(xWrappedParameters->getByIndex(i),UNO_QUERY); if (xParamColumn.is()) { #ifdef DBG_UTIL @@ -1779,7 +1827,19 @@ void askForParameters(const Reference< XSingleSelectQueryComposer >& _xComposer, if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE), xParamColumn)) xParamColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE)) >>= nScale; // and set the value - _xParameters->setObjectWithInfo(i + 1, pFinalValues->Value, nParamType, nScale); + ::std::bit_vector::const_iterator aIter = _aParametersSet.begin(); + ::std::bit_vector::const_iterator aEnd = _aParametersSet.end(); + sal_Int32 j = 0; + sal_Int32 nParamPos = -1; + for(; aIter != aEnd && j <= i; ++aIter) + { + ++nParamPos; + if ( !*aIter ) + { + ++j; + } + } + _xParameters->setObjectWithInfo(nParamPos + 1, pFinalValues->Value, nParamType, nScale); // (the index of the parameters is one-based) } } diff --git a/connectivity/source/commontools/dbtools2.cxx b/connectivity/source/commontools/dbtools2.cxx index 67c4907b2de5..e08c3a33076d 100644 --- a/connectivity/source/commontools/dbtools2.cxx +++ b/connectivity/source/commontools/dbtools2.cxx @@ -86,10 +86,10 @@ namespace dbtools sal_Int32 nPrecision = 0; sal_Int32 nScale = 0; - ::rtl::OUString sQuoteString = xMetaData->getIdentifierQuoteString(); - ::rtl::OUString aSql = ::dbtools::quoteName(sQuoteString,::comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)))); + const ::rtl::OUString sQuoteString = xMetaData->getIdentifierQuoteString(); + ::rtl::OUStringBuffer aSql = ::dbtools::quoteName(sQuoteString,::comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)))); - aSql += ::rtl::OUString::createFromAscii(" "); + aSql.appendAscii(" "); nDataType = nPrecision = nScale = 0; sal_Bool bIsAutoIncrement = sal_False; @@ -143,54 +143,59 @@ namespace dbtools sal_Int32 nParenPos = sTypeName.indexOf('('); if ( nParenPos == -1 ) { - aSql += sTypeName; - aSql += ::rtl::OUString::createFromAscii("("); + aSql.append(sTypeName); + aSql.appendAscii("("); } else { - aSql += sTypeName.copy(0,++nParenPos); + aSql.append(sTypeName.copy(0,++nParenPos)); } if ( nPrecision > 0 && nDataType != DataType::TIMESTAMP ) { - aSql += ::rtl::OUString::valueOf(nPrecision); + aSql.append(nPrecision); if ( (nScale > 0) || (_sCreatePattern.getLength() && sCreateParams.indexOf(_sCreatePattern) != -1) ) - aSql += ::rtl::OUString::createFromAscii(","); + aSql.appendAscii(","); } if ( (nScale > 0) || (_sCreatePattern.getLength() && sCreateParams.indexOf(_sCreatePattern) != -1 ) || nDataType == DataType::TIMESTAMP ) - aSql += ::rtl::OUString::valueOf(nScale); + aSql.append(nScale); if ( nParenPos == -1 ) - aSql += ::rtl::OUString::createFromAscii(")"); + aSql.appendAscii(")"); else { nParenPos = sTypeName.indexOf(')',nParenPos); - aSql += sTypeName.copy(nParenPos); + aSql.append(sTypeName.copy(nParenPos)); } } else - aSql += sTypeName; // simply add the type name + aSql.append(sTypeName); // simply add the type name ::rtl::OUString aDefault = ::comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_DEFAULTVALUE))); - if(aDefault.getLength()) - aSql += ::rtl::OUString::createFromAscii(" DEFAULT ") + sPreFix + aDefault + sPostFix; + if ( aDefault.getLength() ) + { + aSql.append(::rtl::OUString::createFromAscii(" DEFAULT ")); + aSql.append(sPreFix); + aSql.append(aDefault); + aSql.append(sPostFix); + } // if ( aDefault.getLength() ) if(::comphelper::getINT32(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISNULLABLE))) == ColumnValue::NO_NULLS) - aSql += ::rtl::OUString::createFromAscii(" NOT NULL"); + aSql.append(::rtl::OUString::createFromAscii(" NOT NULL")); if ( bIsAutoIncrement && sAutoIncrementValue.getLength()) { - aSql += ::rtl::OUString::createFromAscii(" "); - aSql += sAutoIncrementValue; + aSql.appendAscii(" "); + aSql.append(sAutoIncrementValue); } - return aSql; + return aSql.makeStringAndClear(); } // ----------------------------------------------------------------------------- ::rtl::OUString createStandardCreateStatement(const Reference< XPropertySet >& descriptor,const Reference< XConnection>& _xConnection,const ::rtl::OUString& _sCreatePattern) { - ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("CREATE TABLE "); + ::rtl::OUStringBuffer aSql = ::rtl::OUString::createFromAscii("CREATE TABLE "); ::rtl::OUString sCatalog,sSchema,sTable,sComposedName; Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData(); @@ -204,7 +209,8 @@ namespace dbtools if ( !sComposedName.getLength() ) ::dbtools::throwFunctionSequenceException(_xConnection); - aSql += sComposedName + ::rtl::OUString::createFromAscii(" ("); + aSql.append(sComposedName); + aSql.append(::rtl::OUString::createFromAscii(" (")); // columns Reference<XColumnsSupplier> xColumnSup(descriptor,UNO_QUERY); @@ -220,11 +226,11 @@ namespace dbtools { if ( (xColumns->getByIndex(i) >>= xColProp) && xColProp.is() ) { - aSql += createStandardColumnPart(xColProp,_xConnection,_sCreatePattern); - aSql += ::rtl::OUString::createFromAscii(","); + aSql.append(createStandardColumnPart(xColProp,_xConnection,_sCreatePattern)); + aSql.appendAscii(","); } } - return aSql; + return aSql.makeStringAndClear(); } namespace { @@ -256,7 +262,7 @@ namespace Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData(); ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); - ::rtl::OUString aSql; + ::rtl::OUStringBuffer aSql; // keys Reference<XKeysSupplier> xKeySup(descriptor,UNO_QUERY); Reference<XIndexAccess> xKeys = xKeySup->getKeys(); @@ -286,8 +292,8 @@ namespace ::dbtools::throwFunctionSequenceException(_xConnection); const ::rtl::OUString sQuote = xMetaData->getIdentifierQuoteString(); - aSql += ::rtl::OUString::createFromAscii(" PRIMARY KEY "); - aSql += generateColumnNames(xColumns,xMetaData); + aSql.append(::rtl::OUString::createFromAscii(" PRIMARY KEY ")); + aSql.append(generateColumnNames(xColumns,xMetaData)); } else if(nKeyType == KeyType::UNIQUE) { @@ -297,8 +303,8 @@ namespace ::dbtools::throwFunctionSequenceException(_xConnection); const ::rtl::OUString sQuote = xMetaData->getIdentifierQuoteString(); - aSql += ::rtl::OUString::createFromAscii(" UNIQUE "); - aSql += generateColumnNames(xColumns,xMetaData); + aSql.append(::rtl::OUString::createFromAscii(" UNIQUE ")); + aSql.append(generateColumnNames(xColumns,xMetaData)); } else if(nKeyType == KeyType::FOREIGN) { @@ -309,7 +315,7 @@ namespace if(!xColumns.is() || !xColumns->getCount()) ::dbtools::throwFunctionSequenceException(_xConnection); - aSql += ::rtl::OUString::createFromAscii(" FOREIGN KEY "); + aSql.append(::rtl::OUString::createFromAscii(" FOREIGN KEY ")); ::rtl::OUString sRefTable = getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_REFERENCEDTABLE))); ::dbtools::qualifiedNameComponents(xMetaData, sRefTable, @@ -323,21 +329,21 @@ namespace if ( !sComposedName.getLength() ) ::dbtools::throwFunctionSequenceException(_xConnection); - aSql += generateColumnNames(xColumns,xMetaData); + aSql.append(generateColumnNames(xColumns,xMetaData)); switch(nDeleteRule) { case KeyRule::CASCADE: - aSql += ::rtl::OUString::createFromAscii(" ON DELETE CASCADE "); + aSql.append(::rtl::OUString::createFromAscii(" ON DELETE CASCADE ")); break; case KeyRule::RESTRICT: - aSql += ::rtl::OUString::createFromAscii(" ON DELETE RESTRICT "); + aSql.append(::rtl::OUString::createFromAscii(" ON DELETE RESTRICT ")); break; case KeyRule::SET_NULL: - aSql += ::rtl::OUString::createFromAscii(" ON DELETE SET NULL "); + aSql.append(::rtl::OUString::createFromAscii(" ON DELETE SET NULL ")); break; case KeyRule::SET_DEFAULT: - aSql += ::rtl::OUString::createFromAscii(" ON DELETE SET DEFAULT "); + aSql.append(::rtl::OUString::createFromAscii(" ON DELETE SET DEFAULT ")); break; default: ; @@ -349,13 +355,13 @@ namespace if ( aSql.getLength() ) { - if ( aSql.lastIndexOf(',') == (aSql.getLength()-1) ) - aSql = aSql.replaceAt(aSql.getLength()-1,1,::rtl::OUString::createFromAscii(")")); + if ( aSql.charAt(aSql.getLength()-1) == ',' ) + aSql.setCharAt(aSql.getLength()-1,')'); else - aSql += ::rtl::OUString::createFromAscii(")"); + aSql.appendAscii(")"); } - return aSql; + return aSql.makeStringAndClear(); } // ----------------------------------------------------------------------------- @@ -364,7 +370,7 @@ namespace const ::rtl::OUString& _sCreatePattern) { ::rtl::OUString aSql = ::dbtools::createStandardCreateStatement(descriptor,_xConnection,_sCreatePattern); - ::rtl::OUString sKeyStmt = ::dbtools::createStandardKeyStatement(descriptor,_xConnection); + const ::rtl::OUString sKeyStmt = ::dbtools::createStandardKeyStatement(descriptor,_xConnection); if ( sKeyStmt.getLength() ) aSql += sKeyStmt; else @@ -378,7 +384,7 @@ namespace } namespace { - Reference<XPropertySet> lcl_createSDBCXColumn( + Reference<XPropertySet> lcl_createSDBCXColumn(const Reference<XNameAccess>& _xPrimaryKeyColumns, const Reference<XConnection>& _xConnection, const Any& _aCatalog, const ::rtl::OUString& _aSchema, @@ -418,8 +424,7 @@ namespace const ::rtl::OUString sQuote = xMetaData->getIdentifierQuoteString(); ::rtl::OUString sQuotedName = ::dbtools::quoteName(sQuote,_rName); ::rtl::OUString sComposedName; - sComposedName = composeTableNameForSelect( - _xConnection, getString( _aCatalog ), _aSchema, _aTable ); + sComposedName = composeTableNameForSelect(_xConnection, getString( _aCatalog ), _aSchema, _aTable ); ColumnInformationMap aInfo(_bCase); collectColumnInformation(_xConnection,sComposedName,sQuotedName,aInfo); @@ -439,11 +444,19 @@ namespace { try { - Reference< XResultSet > xPKeys = xMetaData->getPrimaryKeys( _aCatalog, _aSchema, _aTable ); - Reference< XRow > xPKeyRow( xPKeys, UNO_QUERY_THROW ); - while( xPKeys->next() ) // there can be only one primary key + if ( _xPrimaryKeyColumns.is() ) + { + if ( _xPrimaryKeyColumns->hasByName(_rName) ) + nField11 = ColumnValue::NO_NULLS; + + } + else + { + Reference< XResultSet > xPKeys = xMetaData->getPrimaryKeys( _aCatalog, _aSchema, _aTable ); + Reference< XRow > xPKeyRow( xPKeys, UNO_QUERY_THROW ); + while( xPKeys->next() ) // there can be only one primary key { - ::rtl::OUString sKeyColumn = xPKeyRow->getString(4); + ::rtl::OUString sKeyColumn = xPKeyRow->getString(4); if ( aMixCompare(_rName,sKeyColumn) ) { nField11 = ColumnValue::NO_NULLS; @@ -451,6 +464,7 @@ namespace } } } + } catch(SQLException&) { OSL_ENSURE( false, "lcl_createSDBCXColumn: caught an exception!" ); @@ -515,10 +529,33 @@ Reference<XPropertySet> createSDBCXColumn(const Reference<XPropertySet>& _xTable _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema; _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable; - xProp = lcl_createSDBCXColumn(_xConnection,aCatalog, aSchema, aTable, _rName,_rName,_bCase,_bQueryForInfo,_bIsAutoIncrement,_bIsCurrency,_nDataType); + Reference<XKeysSupplier> xKeysSup(_xTable,UNO_QUERY); + Reference<XNameAccess> xPrimaryKeyColumns; + if ( xKeysSup.is() ) + { + const Reference<XIndexAccess> xKeys = xKeysSup->getKeys(); + if ( xKeys.is() ) + { + const sal_Int32 nKeyCount = xKeys->getCount(); + for(sal_Int32 nKeyIter = 0; nKeyIter < nKeyCount;++nKeyIter) + { + const Reference<XPropertySet> xKey(xKeys->getByIndex(nKeyIter),UNO_QUERY_THROW); + sal_Int32 nType = 0; + xKey->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE)) >>= nType; + if ( nType == KeyType::PRIMARY ) + { + const Reference<XColumnsSupplier> xColS(xKey,UNO_QUERY_THROW); + xPrimaryKeyColumns = xColS->getColumns(); + break; + } + } // for(sal_Int32 nKeyIter = 0; nKeyIter < nKeyCount;++) + } + } + + xProp = lcl_createSDBCXColumn(xPrimaryKeyColumns,_xConnection,aCatalog, aSchema, aTable, _rName,_rName,_bCase,_bQueryForInfo,_bIsAutoIncrement,_bIsCurrency,_nDataType); if ( !xProp.is() ) { - xProp = lcl_createSDBCXColumn(_xConnection,aCatalog, aSchema, aTable, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("%")),_rName,_bCase,_bQueryForInfo,_bIsAutoIncrement,_bIsCurrency,_nDataType); + xProp = lcl_createSDBCXColumn(xPrimaryKeyColumns,_xConnection,aCatalog, aSchema, aTable, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("%")),_rName,_bCase,_bQueryForInfo,_bIsAutoIncrement,_bIsCurrency,_nDataType); if ( !xProp.is() ) xProp = new connectivity::sdbcx::OColumn(_rName, ::rtl::OUString(),::rtl::OUString(), @@ -603,7 +640,7 @@ Reference< XTablesSupplier> getDataDefinitionByURLAndConnection( // if we don't get the catalog from the original driver we have to try them all. if ( !xTablesSup.is() ) - { + { // !TODO: Why? Reference< XEnumerationAccess> xEnumAccess( xManager, UNO_QUERY_THROW ); Reference< XEnumeration > xEnum( xEnumAccess->createEnumeration(), UNO_QUERY_THROW ); while ( xEnum.is() && xEnum->hasMoreElements() && !xTablesSup.is() ) @@ -752,6 +789,7 @@ void collectColumnInformation(const Reference< XConnection>& _xConnection, Reference< XResultSetMetaData > xMeta( xSuppMeta->getMetaData(), UNO_QUERY_THROW ); sal_Int32 nCount = xMeta->getColumnCount(); + OSL_ENSURE( nCount != 0, "::dbtools::collectColumnInformation: result set has empty (column-less) meta data!" ); for (sal_Int32 i=1; i <= nCount ; ++i) { _rInfo.insert(ColumnInformationMap::value_type(xMeta->getColumnName(i), diff --git a/connectivity/source/commontools/makefile.mk b/connectivity/source/commontools/makefile.mk index 5b8287f6c826..cb5a4ad3f7aa 100644 --- a/connectivity/source/commontools/makefile.mk +++ b/connectivity/source/commontools/makefile.mk @@ -49,6 +49,8 @@ ENVCFLAGS+=/FR$(SLO)$/ NOOPTFILES= $(SLO)$/RowFunctionParser.obj .ENDIF +ENVCFLAGS += -DBOOST_SPIRIT_USE_OLD_NAMESPACE + # --- Files -------------------------------------------------------- EXCEPTIONSFILES=\ $(SLO)$/predicateinput.obj \ @@ -85,7 +87,9 @@ EXCEPTIONSFILES=\ $(SLO)$/filtermanager.obj \ $(SLO)$/parameters.obj \ $(SLO)$/ParamterSubstitution.obj \ - $(SLO)$/formattedcolumnvalue.obj + $(SLO)$/DriversConfig.obj \ + $(SLO)$/formattedcolumnvalue.obj \ + $(SLO)$/warningscontainer.obj SLOFILES=\ $(EXCEPTIONSFILES) \ diff --git a/connectivity/source/commontools/parameters.cxx b/connectivity/source/commontools/parameters.cxx index d45a7ac849a3..ae55ad3f2680 100644 --- a/connectivity/source/commontools/parameters.cxx +++ b/connectivity/source/commontools/parameters.cxx @@ -54,6 +54,7 @@ #include <comphelper/proparrhlp.hxx> #include <comphelper/broadcasthelper.hxx> #include "connectivity/ParameterCont.hxx" +#include <rtl/ustrbuf.hxx> //........................................................................ namespace dbtools @@ -117,7 +118,7 @@ namespace dbtools //-------------------------------------------------------------------- void ParameterManager::clearAllParameterInformation() { - m_xInnerParamColumns = NULL; + m_xInnerParamColumns.clear(); if ( m_pOuterParameters.is() ) m_pOuterParameters->dispose(); m_pOuterParameters = NULL; @@ -394,24 +395,24 @@ namespace dbtools // did we find links where the detail field refers to a detail column (instead of a parameter name)? if ( !aAdditionalFilterComponents.empty() ) { + const static ::rtl::OUString s_sAnd( RTL_CONSTASCII_USTRINGPARAM( " AND " ) ); // build a conjunction of all the filter components - ::rtl::OUString sAdditionalFilter; + ::rtl::OUStringBuffer sAdditionalFilter; for ( ::std::vector< ::rtl::OUString >::const_iterator aComponent = aAdditionalFilterComponents.begin(); aComponent != aAdditionalFilterComponents.end(); ++aComponent ) { - ::rtl::OUString sBracketed( RTL_CONSTASCII_USTRINGPARAM( "( " ) ); - sBracketed += *aComponent; - sBracketed += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " )" ) ); - if ( sAdditionalFilter.getLength() ) - sAdditionalFilter += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " AND " ) ); - sAdditionalFilter += sBracketed; + sAdditionalFilter.append(s_sAnd); + + sAdditionalFilter.appendAscii("( ",((sal_Int32)(sizeof("( ")-1))); + sAdditionalFilter.append(*aComponent); + sAdditionalFilter.appendAscii(" )",((sal_Int32)(sizeof(" )")-1))); } // now set this filter at the 's filter manager - _rFilterManager.setFilterComponent( FilterManager::fcLinkFilter, sAdditionalFilter ); + _rFilterManager.setFilterComponent( FilterManager::fcLinkFilter, sAdditionalFilter.makeStringAndClear() ); _rColumnsInLinkDetails = true; } @@ -1119,3 +1120,4 @@ namespace dbtools //........................................................................ } // namespace frm //........................................................................ + diff --git a/connectivity/source/commontools/sqlerror.cxx b/connectivity/source/commontools/sqlerror.cxx index 84862b89dc30..825902c9e0b3 100644 --- a/connectivity/source/commontools/sqlerror.cxx +++ b/connectivity/source/commontools/sqlerror.cxx @@ -277,7 +277,7 @@ namespace connectivity } if ( !sState.getLength() ) - sState = ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "S1000" ), RTL_TEXTENCODING_ASCII_US ); + sState = ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "S1000" ) ); return sState; } diff --git a/connectivity/source/commontools/warningscontainer.cxx b/connectivity/source/commontools/warningscontainer.cxx new file mode 100644 index 000000000000..c3cf42b94fb7 --- /dev/null +++ b/connectivity/source/commontools/warningscontainer.cxx @@ -0,0 +1,126 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: warnings.cxx,v $ + * $Revision: 1.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_connectivity.hxx" + +#include "connectivity/warningscontainer.hxx" +#include "connectivity/dbexception.hxx" + +#include <osl/diagnose.h> + +//........................................................................ +namespace dbtools +{ +//........................................................................ + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::sdbc; + using namespace ::com::sun::star::sdb; + + //==================================================================== + //= WarningsContainer + //==================================================================== + //-------------------------------------------------------------------- + static void lcl_concatWarnings( Any& _rChainLeft, const Any& _rChainRight ) + { + if ( !_rChainLeft.hasValue() ) + _rChainLeft = _rChainRight; + else + { + // to travel the chain by reference (and not by value), we need the getValue ... + // looks like a hack, but the meaning of getValue is documented, and it's the only chance for reference-traveling .... + + OSL_ENSURE( SQLExceptionInfo( _rChainLeft ).isValid(), + "lcl_concatWarnings: invalid warnings chain (this will crash)!" ); + + const SQLException* pChainTravel = static_cast< const SQLException* >( _rChainLeft.getValue() ); + SQLExceptionIteratorHelper aReferenceIterHelper( *pChainTravel ); + while ( aReferenceIterHelper.hasMoreElements() ) + pChainTravel = aReferenceIterHelper.next(); + + // reached the end of the chain, and pChainTravel points to the last element + const_cast< SQLException* >( pChainTravel )->NextException = _rChainRight; + } + } + + //-------------------------------------------------------------------- + WarningsContainer::~WarningsContainer() + { + } + + //-------------------------------------------------------------------- + void WarningsContainer::appendWarning(const SQLException& _rWarning) + { + lcl_concatWarnings( m_aOwnWarnings, makeAny( _rWarning ) ); + } + + //-------------------------------------------------------------------- + void WarningsContainer::appendWarning( const SQLContext& _rContext ) + { + lcl_concatWarnings( m_aOwnWarnings, makeAny( _rContext )); + } + + //-------------------------------------------------------------------- + void WarningsContainer::appendWarning(const SQLWarning& _rWarning) + { + lcl_concatWarnings( m_aOwnWarnings, makeAny( _rWarning ) ); + } + + //-------------------------------------------------------------------- + Any SAL_CALL WarningsContainer::getWarnings( ) const + { + Any aAllWarnings; + if ( m_xExternalWarnings.is() ) + aAllWarnings = m_xExternalWarnings->getWarnings(); + + if ( m_aOwnWarnings.hasValue() ) + lcl_concatWarnings( aAllWarnings, m_aOwnWarnings ); + + return aAllWarnings; + } + + //-------------------------------------------------------------------- + void SAL_CALL WarningsContainer::clearWarnings( ) + { + if ( m_xExternalWarnings.is() ) + m_xExternalWarnings->clearWarnings(); + m_aOwnWarnings.clear(); + } + + //-------------------------------------------------------------------- + void WarningsContainer::appendWarning( const ::rtl::OUString& _rWarning, const sal_Char* _pAsciiSQLState, const Reference< XInterface >& _rxContext ) + { + appendWarning( SQLWarning( _rWarning, _rxContext, ::rtl::OUString::createFromAscii( _pAsciiSQLState ), 0, Any() ) ); + } + +//........................................................................ +} // namespace dbtools +//........................................................................ |