/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: dbtools2.cxx,v $ * * $Revision: 1.26 $ * * last change: $Author: vg $ $Date: 2008-01-25 10:31:08 $ * * 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 * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_connectivity.hxx" #ifndef _CONNECTIVITY_DBTOOLS_HXX_ #include "connectivity/dbtools.hxx" #endif #include "connectivity/dbconversion.hxx" #ifndef _DBHELPER_DBCHARSET_HXX_ #include "connectivity/dbcharset.hxx" #endif #include #ifndef CONNECTIVITY_SHAREDRESOURCES_HXX #include "resource/sharedresources.hxx" #endif #ifndef CONNECTIVITY_RESOURCE_COMMON_HRC #include "resource/common_res.hrc" #endif #ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_COLUMNVALUE_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_XROW_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_XRESULTSETMETADATASUPPLIER_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_XDRIVERACCESS_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBCX_XDATADEFINITIONSUPPLIER_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBCX_PRIVILEGE_HPP_ #include #endif #ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_ #include #endif #ifndef _COM_SUN_STAR_CONTAINER_XENUMERATIONACCESS_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBC_KEYRULE_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDBCX_KEYTYPE_HPP_ #include #endif #ifndef CONNECTIVITY_CONNECTION_HXX #include "TConnection.hxx" #endif #ifndef _CONNECTIVITY_SDBCX_COLUMN_HXX_ #include "connectivity/sdbcx/VColumn.hxx" #endif #ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_ #include #endif #ifndef _COM_SUN_STAR_CONTAINER_XCHILD_HPP_ #include #endif #include #include #include //......................................................................... 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) { Reference xMetaData = _xConnection->getMetaData(); ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); ::rtl::OUString sTypeName; sal_Int32 nDataType = 0; 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)))); aSql += ::rtl::OUString::createFromAscii(" "); 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 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; { Reference xRes = xMetaData->getTypeInfo(); if(xRes.is()) { Reference 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); ::rtl::OUString 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 += sTypeName; aSql += ::rtl::OUString::createFromAscii("("); } else { aSql += sTypeName.copy(0,++nParenPos); } if ( nPrecision > 0 && nDataType != DataType::TIMESTAMP ) { aSql += ::rtl::OUString::valueOf(nPrecision); if ( nScale > 0 ) aSql += ::rtl::OUString::createFromAscii(","); } if ( nScale > 0 || nDataType == DataType::TIMESTAMP ) aSql += ::rtl::OUString::valueOf(nScale); if ( nParenPos == -1 ) aSql += ::rtl::OUString::createFromAscii(")"); else { nParenPos = sTypeName.indexOf(')',nParenPos); aSql += sTypeName.copy(nParenPos); } } else aSql += 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(::comphelper::getINT32(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISNULLABLE))) == ColumnValue::NO_NULLS) aSql += ::rtl::OUString::createFromAscii(" NOT NULL"); if ( bIsAutoIncrement && sAutoIncrementValue.getLength()) { aSql += ::rtl::OUString::createFromAscii(" "); aSql += sAutoIncrementValue; } return aSql; } // ----------------------------------------------------------------------------- ::rtl::OUString createStandardCreateStatement(const Reference< XPropertySet >& descriptor,const Reference< XConnection>& _xConnection) { ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("CREATE TABLE "); ::rtl::OUString sCatalog,sSchema,sTable,sComposedName; Reference 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 += sComposedName + ::rtl::OUString::createFromAscii(" ("); // columns Reference xColumnSup(descriptor,UNO_QUERY); Reference 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;igetByIndex(i) >>= xColProp) && xColProp.is() ) { aSql += createStandardColumnPart(xColProp,_xConnection); aSql += ::rtl::OUString::createFromAscii(","); } } return aSql; } namespace { ::rtl::OUString generateColumnNames(const Reference& _xColumns,const Reference& _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;igetByIndex(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 xMetaData = _xConnection->getMetaData(); ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); ::rtl::OUString aSql; // keys Reference xKeySup(descriptor,UNO_QUERY); Reference xKeys = xKeySup->getKeys(); if ( xKeys.is() ) { Reference< XPropertySet > xColProp; Reference xColumns; Reference xColumnSup; ::rtl::OUString sCatalog,sSchema,sTable,sComposedName; sal_Bool bPKey = sal_False; for(sal_Int32 i=0;igetCount();++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(xColProp,UNO_QUERY); xColumns = Reference(xColumnSup->getColumns(),UNO_QUERY); if(!xColumns.is() || !xColumns->getCount()) ::dbtools::throwFunctionSequenceException(_xConnection); const ::rtl::OUString sQuote = xMetaData->getIdentifierQuoteString(); aSql += ::rtl::OUString::createFromAscii(" PRIMARY KEY "); aSql += generateColumnNames(xColumns,xMetaData); } else if(nKeyType == KeyType::UNIQUE) { xColumnSup = Reference(xColProp,UNO_QUERY); xColumns = Reference(xColumnSup->getColumns(),UNO_QUERY); if(!xColumns.is() || !xColumns->getCount()) ::dbtools::throwFunctionSequenceException(_xConnection); const ::rtl::OUString sQuote = xMetaData->getIdentifierQuoteString(); aSql += ::rtl::OUString::createFromAscii(" UNIQUE "); aSql += generateColumnNames(xColumns,xMetaData); } else if(nKeyType == KeyType::FOREIGN) { sal_Int32 nDeleteRule = getINT32(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_DELETERULE))); xColumnSup = Reference(xColProp,UNO_QUERY); xColumns = Reference(xColumnSup->getColumns(),UNO_QUERY); if(!xColumns.is() || !xColumns->getCount()) ::dbtools::throwFunctionSequenceException(_xConnection); aSql += ::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 += generateColumnNames(xColumns,xMetaData); switch(nDeleteRule) { case KeyRule::CASCADE: aSql += ::rtl::OUString::createFromAscii(" ON DELETE CASCADE "); break; case KeyRule::RESTRICT: aSql += ::rtl::OUString::createFromAscii(" ON DELETE RESTRICT "); break; case KeyRule::SET_NULL: aSql += ::rtl::OUString::createFromAscii(" ON DELETE SET NULL "); break; case KeyRule::SET_DEFAULT: aSql += ::rtl::OUString::createFromAscii(" ON DELETE SET DEFAULT "); break; default: ; } } } } } if ( aSql.getLength() ) { if ( aSql.lastIndexOf(',') == (aSql.getLength()-1) ) aSql = aSql.replaceAt(aSql.getLength()-1,1,::rtl::OUString::createFromAscii(")")); else aSql += ::rtl::OUString::createFromAscii(")"); } return aSql; } // ----------------------------------------------------------------------------- ::rtl::OUString createSqlCreateTableStatement( const Reference< XPropertySet >& descriptor, const Reference< XConnection>& _xConnection) { ::rtl::OUString aSql = ::dbtools::createStandardCreateStatement(descriptor,_xConnection); ::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 lcl_createSDBCXColumn( const Reference& _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 xProp; Reference 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 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 { 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, 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(xParent,UNO_QUERY); xParent.set(xChild.is() ? xChild->getParent() : Reference< XInterface >(),UNO_QUERY); xModel.set(xParent,UNO_QUERY); } return xModel; } } // ----------------------------------------------------------------------------- Reference createSDBCXColumn(const Reference& _xTable, const Reference& _xConnection, const ::rtl::OUString& _rName, sal_Bool _bCase, sal_Bool _bQueryForInfo, sal_Bool _bIsAutoIncrement, sal_Bool _bIsCurrency, sal_Int32 _nDataType) { Reference xProp; OSL_ENSURE(_xTable.is(),"Table is NULL!"); if ( !_xTable.is() ) return xProp; ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); Reference 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; xProp = lcl_createSDBCXColumn(_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); if ( !xProp.is() ) xProp = new connectivity::sdbcx::OColumn(_rName, ::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; } // ----------------------------------------------------------------------------- sal_Bool isDataSourcePropertyEnabled(const Reference& _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 ); // if we don't get the catalog from the original driver we have to try them all. if ( !xTablesSup.is() ) { Reference< XEnumerationAccess> xEnumAccess( xManager, UNO_QUERY_THROW ); Reference< XEnumeration > xEnum( xEnumAccess->createEnumeration(), UNO_QUERY_THROW ); while ( xEnum.is() && xEnum->hasMoreElements() && !xTablesSup.is() ) { xEnum->nextElement() >>= xSupp; if ( xSupp.is() ) xTablesSup = xSupp->getDataDefinitionByConnection( _xConnection ); } } } 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(); 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 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 //.........................................................................