diff options
Diffstat (limited to 'connectivity/source/commontools/dbtools2.cxx')
-rw-r--r-- | connectivity/source/commontools/dbtools2.cxx | 974 |
1 files changed, 974 insertions, 0 deletions
diff --git a/connectivity/source/commontools/dbtools2.cxx b/connectivity/source/commontools/dbtools2.cxx new file mode 100644 index 000000000000..c9a878fe1840 --- /dev/null +++ b/connectivity/source/commontools/dbtools2.cxx @@ -0,0 +1,974 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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/dbtools.hxx" +#include "connectivity/dbconversion.hxx" +#include "connectivity/dbcharset.hxx" +#include "connectivity/SQLStatementHelper.hxx" +#include <unotools/confignode.hxx> +#include "resource/sharedresources.hxx" +#include "resource/common_res.hrc" +#include <com/sun/star/sdbc/XConnection.hpp> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> +#include <com/sun/star/sdbcx/XKeysSupplier.hpp> +#include <com/sun/star/sdbc/XDriverAccess.hpp> +#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp> +#include <com/sun/star/sdbcx/Privilege.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/sdbc/KeyRule.hpp> +#include <com/sun/star/sdbcx/KeyType.hpp> +#include "TConnection.hxx" +#include "connectivity/sdbcx/VColumn.hxx" +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/container/XChild.hpp> + +#include <tools/diagnose_ex.h> +#include <unotools/sharedunocomponent.hxx> +#include <comphelper/configurationhelper.hxx> + +//......................................................................... +namespace dbtools +{ +//......................................................................... + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::sdbc; + using namespace ::com::sun::star::sdbcx; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::container; + using namespace ::com::sun::star::frame; + using namespace connectivity; + using namespace comphelper; + +::rtl::OUString createStandardColumnPart(const Reference< XPropertySet >& xColProp,const Reference< XConnection>& _xConnection,ISQLStatementHelper* _pHelper,const ::rtl::OUString& _sCreatePattern) +{ + + Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData(); + + ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); + + ::rtl::OUString sTypeName; + sal_Int32 nDataType = 0; + sal_Int32 nPrecision = 0; + sal_Int32 nScale = 0; + + const ::rtl::OUString sQuoteString = xMetaData->getIdentifierQuoteString(); + ::rtl::OUStringBuffer aSql = ::dbtools::quoteName(sQuoteString,::comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)))); + + aSql.appendAscii(" "); + + nDataType = nPrecision = nScale = 0; + sal_Bool bIsAutoIncrement = sal_False; + xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPENAME)) >>= sTypeName; + xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE)) >>= nDataType; + xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_PRECISION)) >>= nPrecision; + xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCALE)) >>= nScale; + xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT)) >>= bIsAutoIncrement; + + // check if the user enter a specific string to create autoincrement values + ::rtl::OUString sAutoIncrementValue; + Reference<XPropertySetInfo> xPropInfo = xColProp->getPropertySetInfo(); + if ( xPropInfo.is() && xPropInfo->hasPropertyByName(rPropMap.getNameByIndex(PROPERTY_ID_AUTOINCREMENTCREATION)) ) + xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_AUTOINCREMENTCREATION)) >>= sAutoIncrementValue; + // look if we have to use precisions + sal_Bool bUseLiteral = sal_False; + ::rtl::OUString sPreFix,sPostFix,sCreateParams; + { + Reference<XResultSet> xRes = xMetaData->getTypeInfo(); + if(xRes.is()) + { + Reference<XRow> xRow(xRes,UNO_QUERY); + while(xRes->next()) + { + ::rtl::OUString sTypeName2Cmp = xRow->getString(1); + sal_Int32 nType = xRow->getShort(2); + sPreFix = xRow->getString (4); + sPostFix = xRow->getString (5); + sCreateParams = xRow->getString(6); + // first identical type will be used if typename is empty + if ( !sTypeName.getLength() && nType == nDataType ) + sTypeName = sTypeName2Cmp; + + if( sTypeName.equalsIgnoreAsciiCase(sTypeName2Cmp) && nType == nDataType && sCreateParams.getLength() && !xRow->wasNull()) + { + bUseLiteral = sal_True; + break; + } + } + } + } + + sal_Int32 nIndex = 0; + if ( sAutoIncrementValue.getLength() && (nIndex = sTypeName.indexOf(sAutoIncrementValue)) != -1 ) + { + sTypeName = sTypeName.replaceAt(nIndex,sTypeName.getLength() - nIndex,::rtl::OUString()); + } + + if ( (nPrecision > 0 || nScale > 0) && bUseLiteral ) + { + sal_Int32 nParenPos = sTypeName.indexOf('('); + if ( nParenPos == -1 ) + { + aSql.append(sTypeName); + aSql.appendAscii("("); + } + else + { + aSql.append(sTypeName.copy(0,++nParenPos)); + } + + if ( nPrecision > 0 && nDataType != DataType::TIMESTAMP ) + { + aSql.append(nPrecision); + if ( (nScale > 0) || (_sCreatePattern.getLength() && sCreateParams.indexOf(_sCreatePattern) != -1) ) + aSql.appendAscii(","); + } + if ( (nScale > 0) || (_sCreatePattern.getLength() && sCreateParams.indexOf(_sCreatePattern) != -1 ) || nDataType == DataType::TIMESTAMP ) + aSql.append(nScale); + + if ( nParenPos == -1 ) + aSql.appendAscii(")"); + else + { + nParenPos = sTypeName.indexOf(')',nParenPos); + aSql.append(sTypeName.copy(nParenPos)); + } + } + else + aSql.append(sTypeName); // simply add the type name + + ::rtl::OUString aDefault = ::comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_DEFAULTVALUE))); + 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.append(::rtl::OUString::createFromAscii(" NOT NULL")); + + if ( bIsAutoIncrement && sAutoIncrementValue.getLength()) + { + aSql.appendAscii(" "); + aSql.append(sAutoIncrementValue); + } + + if ( _pHelper ) + _pHelper->addComment(xColProp,aSql); + + return aSql.makeStringAndClear(); +} +// ----------------------------------------------------------------------------- + +::rtl::OUString createStandardCreateStatement(const Reference< XPropertySet >& descriptor,const Reference< XConnection>& _xConnection,ISQLStatementHelper* _pHelper,const ::rtl::OUString& _sCreatePattern) +{ + ::rtl::OUStringBuffer aSql = ::rtl::OUString::createFromAscii("CREATE TABLE "); + ::rtl::OUString sCatalog,sSchema,sTable,sComposedName; + + Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData(); + ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); + + descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)) >>= sCatalog; + descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= sSchema; + descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= sTable; + + sComposedName = ::dbtools::composeTableName( xMetaData, sCatalog, sSchema, sTable, sal_True, ::dbtools::eInTableDefinitions ); + if ( !sComposedName.getLength() ) + ::dbtools::throwFunctionSequenceException(_xConnection); + + aSql.append(sComposedName); + aSql.append(::rtl::OUString::createFromAscii(" (")); + + // columns + Reference<XColumnsSupplier> xColumnSup(descriptor,UNO_QUERY); + Reference<XIndexAccess> xColumns(xColumnSup->getColumns(),UNO_QUERY); + // check if there are columns + if(!xColumns.is() || !xColumns->getCount()) + ::dbtools::throwFunctionSequenceException(_xConnection); + + Reference< XPropertySet > xColProp; + + sal_Int32 nCount = xColumns->getCount(); + for(sal_Int32 i=0;i<nCount;++i) + { + if ( (xColumns->getByIndex(i) >>= xColProp) && xColProp.is() ) + { + aSql.append(createStandardColumnPart(xColProp,_xConnection,_pHelper,_sCreatePattern)); + aSql.appendAscii(","); + } + } + return aSql.makeStringAndClear(); +} +namespace +{ + ::rtl::OUString generateColumnNames(const Reference<XIndexAccess>& _xColumns,const Reference<XDatabaseMetaData>& _xMetaData) + { + ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); + static const ::rtl::OUString sComma(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","))); + + const ::rtl::OUString sQuote(_xMetaData->getIdentifierQuoteString()); + ::rtl::OUString sSql = ::rtl::OUString::createFromAscii(" ("); + Reference< XPropertySet > xColProp; + + sal_Int32 nColCount = _xColumns->getCount(); + for(sal_Int32 i=0;i<nColCount;++i) + { + if ( (_xColumns->getByIndex(i) >>= xColProp) && xColProp.is() ) + sSql += ::dbtools::quoteName(sQuote,::comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)))) + + sComma; + } + + if ( nColCount ) + sSql = sSql.replaceAt(sSql.getLength()-1,1,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"))); + return sSql; + } +} +// ----------------------------------------------------------------------------- +::rtl::OUString createStandardKeyStatement(const Reference< XPropertySet >& descriptor,const Reference< XConnection>& _xConnection) +{ + Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData(); + ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); + + ::rtl::OUStringBuffer aSql; + // keys + Reference<XKeysSupplier> xKeySup(descriptor,UNO_QUERY); + Reference<XIndexAccess> xKeys = xKeySup->getKeys(); + if ( xKeys.is() ) + { + Reference< XPropertySet > xColProp; + Reference<XIndexAccess> xColumns; + Reference<XColumnsSupplier> xColumnSup; + ::rtl::OUString sCatalog,sSchema,sTable,sComposedName; + sal_Bool bPKey = sal_False; + for(sal_Int32 i=0;i<xKeys->getCount();++i) + { + if ( (xKeys->getByIndex(i) >>= xColProp) && xColProp.is() ) + { + + sal_Int32 nKeyType = ::comphelper::getINT32(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_TYPE))); + + if ( nKeyType == KeyType::PRIMARY ) + { + if(bPKey) + ::dbtools::throwFunctionSequenceException(_xConnection); + + bPKey = sal_True; + xColumnSup = Reference<XColumnsSupplier>(xColProp,UNO_QUERY); + xColumns = Reference<XIndexAccess>(xColumnSup->getColumns(),UNO_QUERY); + if(!xColumns.is() || !xColumns->getCount()) + ::dbtools::throwFunctionSequenceException(_xConnection); + + const ::rtl::OUString sQuote = xMetaData->getIdentifierQuoteString(); + aSql.append(::rtl::OUString::createFromAscii(" PRIMARY KEY ")); + aSql.append(generateColumnNames(xColumns,xMetaData)); + } + else if(nKeyType == KeyType::UNIQUE) + { + xColumnSup = Reference<XColumnsSupplier>(xColProp,UNO_QUERY); + xColumns = Reference<XIndexAccess>(xColumnSup->getColumns(),UNO_QUERY); + if(!xColumns.is() || !xColumns->getCount()) + ::dbtools::throwFunctionSequenceException(_xConnection); + + const ::rtl::OUString sQuote = xMetaData->getIdentifierQuoteString(); + aSql.append(::rtl::OUString::createFromAscii(" UNIQUE ")); + aSql.append(generateColumnNames(xColumns,xMetaData)); + } + else if(nKeyType == KeyType::FOREIGN) + { + sal_Int32 nDeleteRule = getINT32(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_DELETERULE))); + + xColumnSup = Reference<XColumnsSupplier>(xColProp,UNO_QUERY); + xColumns = Reference<XIndexAccess>(xColumnSup->getColumns(),UNO_QUERY); + if(!xColumns.is() || !xColumns->getCount()) + ::dbtools::throwFunctionSequenceException(_xConnection); + + aSql.append(::rtl::OUString::createFromAscii(" FOREIGN KEY ")); + ::rtl::OUString sRefTable = getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_REFERENCEDTABLE))); + ::dbtools::qualifiedNameComponents(xMetaData, + sRefTable, + sCatalog, + sSchema, + sTable, + ::dbtools::eInDataManipulation); + sComposedName = ::dbtools::composeTableName( xMetaData, sCatalog, sSchema, sTable, sal_True, ::dbtools::eInTableDefinitions ); + + + if ( !sComposedName.getLength() ) + ::dbtools::throwFunctionSequenceException(_xConnection); + + aSql.append(generateColumnNames(xColumns,xMetaData)); + + switch(nDeleteRule) + { + case KeyRule::CASCADE: + aSql.append(::rtl::OUString::createFromAscii(" ON DELETE CASCADE ")); + break; + case KeyRule::RESTRICT: + aSql.append(::rtl::OUString::createFromAscii(" ON DELETE RESTRICT ")); + break; + case KeyRule::SET_NULL: + aSql.append(::rtl::OUString::createFromAscii(" ON DELETE SET NULL ")); + break; + case KeyRule::SET_DEFAULT: + aSql.append(::rtl::OUString::createFromAscii(" ON DELETE SET DEFAULT ")); + break; + default: + ; + } + } + } + } + } + + if ( aSql.getLength() ) + { + if ( aSql.charAt(aSql.getLength()-1) == ',' ) + aSql.setCharAt(aSql.getLength()-1,')'); + else + aSql.appendAscii(")"); + } + + return aSql.makeStringAndClear(); + +} +// ----------------------------------------------------------------------------- +::rtl::OUString createSqlCreateTableStatement( const Reference< XPropertySet >& descriptor, + const Reference< XConnection>& _xConnection, + ISQLStatementHelper* _pHelper, + const ::rtl::OUString& _sCreatePattern) +{ + ::rtl::OUString aSql = ::dbtools::createStandardCreateStatement(descriptor,_xConnection,_pHelper,_sCreatePattern); + const ::rtl::OUString sKeyStmt = ::dbtools::createStandardKeyStatement(descriptor,_xConnection); + if ( sKeyStmt.getLength() ) + aSql += sKeyStmt; + else + { + if ( aSql.lastIndexOf(',') == (aSql.getLength()-1) ) + aSql = aSql.replaceAt(aSql.getLength()-1,1,::rtl::OUString::createFromAscii(")")); + else + aSql += ::rtl::OUString::createFromAscii(")"); + } + return aSql; +} +namespace +{ + Reference<XPropertySet> lcl_createSDBCXColumn(const Reference<XNameAccess>& _xPrimaryKeyColumns, + const Reference<XConnection>& _xConnection, + const Any& _aCatalog, + const ::rtl::OUString& _aSchema, + const ::rtl::OUString& _aTable, + const ::rtl::OUString& _rQueryName, + const ::rtl::OUString& _rName, + sal_Bool _bCase, + sal_Bool _bQueryForInfo, + sal_Bool _bIsAutoIncrement, + sal_Bool _bIsCurrency, + sal_Int32 _nDataType) + { + Reference<XPropertySet> xProp; + Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData(); + Reference< XResultSet > xResult = xMetaData->getColumns(_aCatalog, _aSchema, _aTable, _rQueryName); + + if ( xResult.is() ) + { + UStringMixEqual aMixCompare(_bCase); + Reference< XRow > xRow(xResult,UNO_QUERY); + while( xResult->next() ) + { + if ( aMixCompare(xRow->getString(4),_rName) ) + { + 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 sField12 = xRow->getString(12), + sField13 = xRow->getString(13); + ::comphelper::disposeComponent(xRow); + + sal_Bool bAutoIncrement = _bIsAutoIncrement + ,bIsCurrency = _bIsCurrency; + if ( _bQueryForInfo ) + { + const ::rtl::OUString sQuote = xMetaData->getIdentifierQuoteString(); + ::rtl::OUString sQuotedName = ::dbtools::quoteName(sQuote,_rName); + ::rtl::OUString sComposedName; + sComposedName = composeTableNameForSelect(_xConnection, getString( _aCatalog ), _aSchema, _aTable ); + + ColumnInformationMap aInfo(_bCase); + collectColumnInformation(_xConnection,sComposedName,sQuotedName,aInfo); + ColumnInformationMap::iterator aIter = aInfo.begin(); + if ( aIter != aInfo.end() ) + { + bAutoIncrement = aIter->second.first.first; + bIsCurrency = aIter->second.first.second; + if ( DataType::OTHER == nField5 ) + nField5 = aIter->second.second; + } + } + else if ( DataType::OTHER == nField5 ) + nField5 = _nDataType; + + if ( nField11 != ColumnValue::NO_NULLS ) + { + try + { + 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); + if ( aMixCompare(_rName,sKeyColumn) ) + { + nField11 = ColumnValue::NO_NULLS; + break; + } + } + } + } + catch(SQLException&) + { + OSL_ENSURE( false, "lcl_createSDBCXColumn: caught an exception!" ); + } + } + + connectivity::sdbcx::OColumn* pRet = new connectivity::sdbcx::OColumn(_rName, + aField6, + sField13, + sField12, + nField11, + nField7, + nField9, + nField5, + bAutoIncrement, + sal_False, + bIsCurrency, + _bCase); + + xProp = pRet; + break; + } + } + } + + return xProp; + } + //------------------------------------------------------------------ + Reference< XModel> lcl_getXModel(const Reference< XInterface>& _xIface) + { + Reference< XInterface > xParent = _xIface; + Reference< XModel > xModel(xParent,UNO_QUERY);; + while( xParent.is() && !xModel.is() ) + { + Reference<XChild> xChild(xParent,UNO_QUERY); + xParent.set(xChild.is() ? xChild->getParent() : Reference< XInterface >(),UNO_QUERY); + xModel.set(xParent,UNO_QUERY); + } + return xModel; + } +} +// ----------------------------------------------------------------------------- +Reference<XPropertySet> createSDBCXColumn(const Reference<XPropertySet>& _xTable, + const Reference<XConnection>& _xConnection, + const ::rtl::OUString& _rName, + sal_Bool _bCase, + sal_Bool _bQueryForInfo, + sal_Bool _bIsAutoIncrement, + sal_Bool _bIsCurrency, + sal_Int32 _nDataType) +{ + Reference<XPropertySet> xProp; + OSL_ENSURE(_xTable.is(),"Table is NULL!"); + if ( !_xTable.is() ) + return xProp; + + ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); + Reference<XDatabaseMetaData> xMetaData = _xConnection->getMetaData(); + Any aCatalog; + aCatalog = _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)); + + ::rtl::OUString aSchema, aTable; + _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema; + _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable; + + Reference<XNameAccess> xPrimaryKeyColumns = getPrimaryKeyColumns_throw(_xTable); + + xProp = lcl_createSDBCXColumn(xPrimaryKeyColumns,_xConnection,aCatalog, aSchema, aTable, _rName,_rName,_bCase,_bQueryForInfo,_bIsAutoIncrement,_bIsCurrency,_nDataType); + if ( !xProp.is() ) + { + 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(),::rtl::OUString(), + ColumnValue::NULLABLE_UNKNOWN, + 0, + 0, + DataType::VARCHAR, + _bIsAutoIncrement, + sal_False, + _bIsCurrency, + _bCase); + + } + + return xProp; +} + +// ----------------------------------------------------------------------------- +bool getBooleanDataSourceSetting( const Reference< XConnection >& _rxConnection, const sal_Char* _pAsciiSettingName ) +{ + bool bValue( false ); + try + { + Reference< XPropertySet> xDataSourceProperties( findDataSource( _rxConnection ), UNO_QUERY ); + OSL_ENSURE( xDataSourceProperties.is(), "::dbtools::getBooleanDataSourceSetting: somebody is using this with a non-SDB-level connection!" ); + if ( xDataSourceProperties.is() ) + { + Reference< XPropertySet > xSettings( + xDataSourceProperties->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Settings") ) ), + UNO_QUERY_THROW + ); + OSL_VERIFY( xSettings->getPropertyValue( ::rtl::OUString::createFromAscii( _pAsciiSettingName ) ) >>= bValue ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return bValue; +} +// ------------------------------------------------------------------------- +bool getDataSourceSetting( const Reference< XInterface >& _xChild, const ::rtl::OUString& _sAsciiSettingsName, + Any& /* [out] */ _rSettingsValue ) +{ + bool bIsPresent = false; + try + { + const Reference< XPropertySet> xDataSourceProperties( findDataSource( _xChild ), UNO_QUERY ); + OSL_ENSURE( xDataSourceProperties.is(), "getDataSourceSetting: invalid data source object!" ); + if ( !xDataSourceProperties.is() ) + return false; + + const Reference< XPropertySet > xSettings( + xDataSourceProperties->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Settings") ) ), + UNO_QUERY_THROW + ); + + _rSettingsValue = xSettings->getPropertyValue( _sAsciiSettingsName ); + bIsPresent = true; + } + catch( const Exception& ) + { + bIsPresent = false; + } + return bIsPresent; +} +// ------------------------------------------------------------------------- +bool getDataSourceSetting( const Reference< XInterface >& _rxDataSource, const sal_Char* _pAsciiSettingsName, + Any& /* [out] */ _rSettingsValue ) +{ + ::rtl::OUString sAsciiSettingsName = ::rtl::OUString::createFromAscii(_pAsciiSettingsName); + return getDataSourceSetting( _rxDataSource, sAsciiSettingsName,_rSettingsValue ); +} +// ----------------------------------------------------------------------------- +sal_Bool isDataSourcePropertyEnabled(const Reference<XInterface>& _xProp,const ::rtl::OUString& _sProperty,sal_Bool _bDefault) +{ + sal_Bool bEnabled = _bDefault; + try + { + Reference< XPropertySet> xProp(findDataSource(_xProp),UNO_QUERY); + if ( xProp.is() ) + { + Sequence< PropertyValue > aInfo; + xProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Info"))) >>= aInfo; + const PropertyValue* pValue =::std::find_if(aInfo.getConstArray(), + aInfo.getConstArray() + aInfo.getLength(), + ::std::bind2nd(TPropertyValueEqualFunctor(),_sProperty)); + if ( pValue && pValue != (aInfo.getConstArray() + aInfo.getLength()) ) + pValue->Value >>= bEnabled; + } + } + catch(SQLException&) + { + DBG_UNHANDLED_EXCEPTION(); + } + return bEnabled; +} +// ----------------------------------------------------------------------------- +Reference< XTablesSupplier> getDataDefinitionByURLAndConnection( + const ::rtl::OUString& _rsUrl, + const Reference< XConnection>& _xConnection, + const Reference< XMultiServiceFactory>& _rxFactory) +{ + Reference< XTablesSupplier> xTablesSup; + try + { + Reference< XDriverAccess> xManager( + _rxFactory->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.sdbc.DriverManager") ), + UNO_QUERY_THROW ); + Reference< XDataDefinitionSupplier > xSupp( xManager->getDriverByURL( _rsUrl ), UNO_QUERY ); + + if ( xSupp.is() ) + { + xTablesSup = xSupp->getDataDefinitionByConnection( _xConnection ); + OSL_ENSURE(xTablesSup.is(),"No table supplier!"); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return xTablesSup; +} + +// ----------------------------------------------------------------------------- +sal_Int32 getTablePrivileges(const Reference< XDatabaseMetaData>& _xMetaData, + const ::rtl::OUString& _sCatalog, + const ::rtl::OUString& _sSchema, + const ::rtl::OUString& _sTable) +{ + OSL_ENSURE(_xMetaData.is(),"Invalid metadata!"); + sal_Int32 nPrivileges = 0; + try + { + Any aVal; + if(_sCatalog.getLength()) + aVal <<= _sCatalog; + Reference< XResultSet > xPrivileges = _xMetaData->getTablePrivileges(aVal, _sSchema, _sTable); + Reference< XRow > xCurrentRow(xPrivileges, UNO_QUERY); + + if ( xCurrentRow.is() ) + { + ::rtl::OUString sUserWorkingFor = _xMetaData->getUserName(); + static const ::rtl::OUString sSELECT = ::rtl::OUString::createFromAscii("SELECT"); + static const ::rtl::OUString sINSERT = ::rtl::OUString::createFromAscii("INSERT"); + static const ::rtl::OUString sUPDATE = ::rtl::OUString::createFromAscii("UPDATE"); + static const ::rtl::OUString sDELETE = ::rtl::OUString::createFromAscii("DELETE"); + static const ::rtl::OUString sREAD = ::rtl::OUString::createFromAscii("READ"); + static const ::rtl::OUString sCREATE = ::rtl::OUString::createFromAscii("CREATE"); + static const ::rtl::OUString sALTER = ::rtl::OUString::createFromAscii("ALTER"); + static const ::rtl::OUString sREFERENCE = ::rtl::OUString::createFromAscii("REFERENCE"); + static const ::rtl::OUString sDROP = ::rtl::OUString::createFromAscii("DROP"); + // after creation the set is positioned before the first record, per definitionem +#ifdef DBG_UTIL + Reference< XResultSetMetaDataSupplier > xSup(xPrivileges,UNO_QUERY); + if ( xSup.is() ) + { + Reference< XResultSetMetaData > xRsMetaData = xSup->getMetaData(); + if ( xRsMetaData.is() ) + { + sal_Int32 nCount = xRsMetaData->getColumnCount(); + for (sal_Int32 i=1; i<=nCount; ++i) + { + ::rtl::OUString sColumnName = xRsMetaData->getColumnName(i); + } + } + } +#endif + + ::rtl::OUString sPrivilege, sGrantee; + while ( xPrivileges->next() ) + { +#ifdef DBG_UTIL + ::rtl::OUString sCat, sSchema, sName, sGrantor, sGrantable; + sCat = xCurrentRow->getString(1); + sSchema = xCurrentRow->getString(2); + sName = xCurrentRow->getString(3); + sGrantor = xCurrentRow->getString(4); +#endif + sGrantee = xCurrentRow->getString(5); + sPrivilege = xCurrentRow->getString(6); +#ifdef DBG_UTIL + sGrantable = xCurrentRow->getString(7); +#endif + + if (!sUserWorkingFor.equalsIgnoreAsciiCase(sGrantee)) + continue; + + if (sPrivilege.equalsIgnoreAsciiCase(sSELECT)) + nPrivileges |= Privilege::SELECT; + else if (sPrivilege.equalsIgnoreAsciiCase(sINSERT)) + nPrivileges |= Privilege::INSERT; + else if (sPrivilege.equalsIgnoreAsciiCase(sUPDATE)) + nPrivileges |= Privilege::UPDATE; + else if (sPrivilege.equalsIgnoreAsciiCase(sDELETE)) + nPrivileges |= Privilege::DELETE; + else if (sPrivilege.equalsIgnoreAsciiCase(sREAD)) + nPrivileges |= Privilege::READ; + else if (sPrivilege.equalsIgnoreAsciiCase(sCREATE)) + nPrivileges |= Privilege::CREATE; + else if (sPrivilege.equalsIgnoreAsciiCase(sALTER)) + nPrivileges |= Privilege::ALTER; + else if (sPrivilege.equalsIgnoreAsciiCase(sREFERENCE)) + nPrivileges |= Privilege::REFERENCE; + else if (sPrivilege.equalsIgnoreAsciiCase(sDROP)) + nPrivileges |= Privilege::DROP; + } + } + disposeComponent(xPrivileges); + } + catch(const SQLException& e) + { + static ::rtl::OUString sNotSupportedState = ::rtl::OUString::createFromAscii("IM001"); + // some drivers don't support any privileges so we assume that we are allowed to do all we want :-) + if(e.SQLState == sNotSupportedState) + nPrivileges |= Privilege::DROP | + Privilege::REFERENCE | + Privilege::ALTER | + Privilege::CREATE | + Privilege::READ | + Privilege::DELETE | + Privilege::UPDATE | + Privilege::INSERT | + Privilege::SELECT; + else + OSL_ENSURE(0,"Could not collect the privileges !"); + } + return nPrivileges; +} +// ----------------------------------------------------------------------------- +// we need some more information about the column +void collectColumnInformation(const Reference< XConnection>& _xConnection, + const ::rtl::OUString& _sComposedName, + const ::rtl::OUString& _rName, + ColumnInformationMap& _rInfo) +{ + static ::rtl::OUString STR_WHERE = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" WHERE ")); + + ::rtl::OUString sSelect = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT ")); + sSelect += _rName; + sSelect += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM ")); + sSelect += _sComposedName; + sSelect += STR_WHERE; + sSelect += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0 = 1")); + + try + { + ::utl::SharedUNOComponent< XStatement > xStmt( _xConnection->createStatement() ); + Reference< XPropertySet > xStatementProps( xStmt, UNO_QUERY_THROW ); + xStatementProps->setPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING ), makeAny( (sal_Bool)sal_False ) ); + Reference< XResultSet > xResult( xStmt->executeQuery( sSelect ), UNO_QUERY_THROW ); + Reference< XResultSetMetaDataSupplier > xSuppMeta( xResult, UNO_QUERY_THROW ); + 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), + ColumnInformation(TBoolPair(xMeta->isAutoIncrement(i),xMeta->isCurrency(i)),xMeta->getColumnType(i)))); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + +// ----------------------------------------------------------------------------- +bool isEmbeddedInDatabase( const Reference< XInterface >& _rxComponent, Reference< XConnection >& _rxActualConnection ) +{ + bool bIsEmbedded = false; + try + { + Reference< XModel > xModel = lcl_getXModel( _rxComponent ); + + if ( xModel.is() ) + { + Sequence< PropertyValue > aArgs = xModel->getArgs(); + const PropertyValue* pIter = aArgs.getConstArray(); + const PropertyValue* pEnd = pIter + aArgs.getLength(); + for(;pIter != pEnd;++pIter) + { + if ( pIter->Name.equalsAscii("ComponentData") ) + { + Sequence<PropertyValue> aDocumentContext; + pIter->Value >>= aDocumentContext; + const PropertyValue* pContextIter = aDocumentContext.getConstArray(); + const PropertyValue* pContextEnd = pContextIter + aDocumentContext.getLength(); + for(;pContextIter != pContextEnd;++pContextIter) + { + if ( pContextIter->Name.equalsAscii( "ActiveConnection" ) + && ( pContextIter->Value >>= _rxActualConnection ) + ) + { + bIsEmbedded = true; + break; + } + } + break; + } + } + } + } + catch(Exception&) + { + // not intereseted in + } + return bIsEmbedded; +} +// ----------------------------------------------------------------------------- +namespace +{ + ::rtl::OUString lcl_getEncodingName( rtl_TextEncoding _eEncoding ) + { + ::rtl::OUString sEncodingName; + + OCharsetMap aCharsets; + OCharsetMap::CharsetIterator aEncodingPos = aCharsets.find( _eEncoding ); + OSL_ENSURE( aEncodingPos != aCharsets.end(), "lcl_getEncodingName: *which* encoding?" ); + if ( aEncodingPos != aCharsets.end() ) + sEncodingName = (*aEncodingPos).getIanaName(); + + return sEncodingName; + } +} + +// ----------------------------------------------------------------------------- +sal_Int32 DBTypeConversion::convertUnicodeString( const ::rtl::OUString& _rSource, ::rtl::OString& _rDest, rtl_TextEncoding _eEncoding ) SAL_THROW((com::sun::star::sdbc::SQLException)) +{ + if ( !rtl_convertUStringToString( &_rDest.pData, _rSource.getStr(), _rSource.getLength(), + _eEncoding, + RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | + RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE | + RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 | + RTL_UNICODETOTEXT_FLAGS_NOCOMPOSITE ) + ) + { + SharedResources aResources; + ::rtl::OUString sMessage = aResources.getResourceStringWithSubstitution( STR_CANNOT_CONVERT_STRING, + "$string$", _rSource, + "$charset$", lcl_getEncodingName( _eEncoding ) + ); + + throw SQLException( + sMessage, + NULL, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "22018" ) ), + 22018, + Any() + ); + } + + return _rDest.getLength(); +} + +// ----------------------------------------------------------------------------- +sal_Int32 DBTypeConversion::convertUnicodeStringToLength( const ::rtl::OUString& _rSource, ::rtl::OString& _rDest, + sal_Int32 _nMaxLen, rtl_TextEncoding _eEncoding ) SAL_THROW((SQLException)) +{ + sal_Int32 nLen = convertUnicodeString( _rSource, _rDest, _eEncoding ); + if ( nLen > _nMaxLen ) + { + SharedResources aResources; + ::rtl::OUString sMessage = aResources.getResourceStringWithSubstitution( STR_STRING_LENGTH_EXCEEDED, + "$string$", _rSource, + "$maxlen$", ::rtl::OUString::valueOf( _nMaxLen ), + "$charset$", lcl_getEncodingName( _eEncoding ) + ); + + throw SQLException( + sMessage, + NULL, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "22001" ) ), + 22001, + Any() + ); + } + + return nLen; +} +::rtl::OUString lcl_getReportEngines() +{ + static ::rtl::OUString s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.DataAccess/ReportEngines")); + return s_sNodeName; +} +// ----------------------------------------------------------------------------- +::rtl::OUString lcl_getDefaultReportEngine() +{ + static ::rtl::OUString s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("DefaultReportEngine")); + return s_sNodeName; +} +// ----------------------------------------------------------------------------- +::rtl::OUString lcl_getReportEngineNames() +{ + static ::rtl::OUString s_sNodeName(RTL_CONSTASCII_USTRINGPARAM("ReportEngineNames")); + return s_sNodeName; +} +// ----------------------------------------------------------------------------- +::rtl::OUString getDefaultReportEngineServiceName(const Reference< XMultiServiceFactory >& _rxORB) +{ + ::utl::OConfigurationTreeRoot aReportEngines = ::utl::OConfigurationTreeRoot::createWithServiceFactory( + _rxORB, lcl_getReportEngines(), -1, ::utl::OConfigurationTreeRoot::CM_READONLY); + + if ( aReportEngines.isValid() ) + { + ::rtl::OUString sDefaultReportEngineName; + aReportEngines.getNodeValue(lcl_getDefaultReportEngine()) >>= sDefaultReportEngineName; + if ( sDefaultReportEngineName.getLength() ) + { + ::utl::OConfigurationNode aReportEngineNames = aReportEngines.openNode(lcl_getReportEngineNames()); + if ( aReportEngineNames.isValid() ) + { + ::utl::OConfigurationNode aReportEngine = aReportEngineNames.openNode(sDefaultReportEngineName); + if ( aReportEngine.isValid() ) + { + ::rtl::OUString sRet; + const static ::rtl::OUString s_sService(RTL_CONSTASCII_USTRINGPARAM("ServiceName")); + aReportEngine.getNodeValue(s_sService) >>= sRet; + return sRet; + } + } + } + else + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.report.pentaho.SOReportJobFactory")); + } + else + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.report.pentaho.SOReportJobFactory")); + return ::rtl::OUString(); +} +// ----------------------------------------------------------------------------- +//......................................................................... +} // namespace dbtools +//......................................................................... + |