/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_connectivity.hxx" #include "connectivity/TIndexes.hxx" #include "connectivity/TIndex.hxx" #include #include #include #include #include "connectivity/TTableHelper.hxx" #include "TConnection.hxx" #include #include using namespace connectivity; using namespace connectivity::sdbcx; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::sdbcx; using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::container; using namespace ::com::sun::star::lang; using namespace cppu; typedef connectivity::sdbcx::OCollection OCollection_TYPE; // ----------------------------------------------------------------------------- OIndexesHelper::OIndexesHelper(OTableHelper* _pTable, ::osl::Mutex& _rMutex, const ::std::vector< ::rtl::OUString> &_rVector ) : OCollection(*_pTable,sal_True,_rMutex,_rVector) ,m_pTable(_pTable) { } // ----------------------------------------------------------------------------- sdbcx::ObjectType OIndexesHelper::createObject(const ::rtl::OUString& _rName) { Reference< XConnection> xConnection = m_pTable->getConnection(); if ( !xConnection.is() ) return NULL; sdbcx::ObjectType xRet; ::rtl::OUString aName,aQualifier; sal_Int32 nLen = _rName.indexOf('.'); if ( nLen != -1 ) { aQualifier = _rName.copy(0,nLen); aName = _rName.copy(nLen+1); } else aName = _rName; ::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; Any aCatalog = m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)); Reference< XResultSet > xResult = m_pTable->getMetaData()->getIndexInfo(aCatalog,aSchema,aTable,sal_False,sal_False); if ( xResult.is() ) { Reference< XRow > xRow(xResult,UNO_QUERY); while( xResult->next() ) { sal_Bool bUnique = !xRow->getBoolean(4); if((!aQualifier.getLength() || xRow->getString(5) == aQualifier ) && xRow->getString(6) == aName) { sal_Int32 nClustered = xRow->getShort(7); sal_Bool bPrimarKeyIndex = sal_False; xRow.clear(); xResult.clear(); try { xResult = m_pTable->getMetaData()->getPrimaryKeys(aCatalog,aSchema,aTable); xRow.set(xResult,UNO_QUERY); if ( xRow.is() && xResult->next() ) // there can be only one primary key { bPrimarKeyIndex = xRow->getString(6) == aName; } } catch(Exception) { } OIndexHelper* pRet = new OIndexHelper(m_pTable,aName,aQualifier,bUnique, bPrimarKeyIndex, nClustered == IndexType::CLUSTERED); xRet = pRet; break; } } } return xRet; } // ------------------------------------------------------------------------- void OIndexesHelper::impl_refresh() throw(RuntimeException) { m_pTable->refreshIndexes(); } // ------------------------------------------------------------------------- Reference< XPropertySet > OIndexesHelper::createDescriptor() { return new OIndexHelper(m_pTable); } // ------------------------------------------------------------------------- // XAppend sdbcx::ObjectType OIndexesHelper::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor ) { Reference< XConnection> xConnection = m_pTable->getConnection(); if ( !xConnection.is() ) return NULL; if ( m_pTable->isNew() ) return cloneDescriptor( descriptor ); if ( m_pTable->getIndexService().is() ) { m_pTable->getIndexService()->addIndex(m_pTable,descriptor); } else { ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); ::rtl::OUStringBuffer aSql( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CREATE "))); ::rtl::OUString aQuote = m_pTable->getMetaData()->getIdentifierQuoteString( ); ::rtl::OUString aDot = ::rtl::OUString::createFromAscii("."); if(comphelper::getBOOL(descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISUNIQUE)))) aSql.appendAscii("UNIQUE "); aSql.appendAscii("INDEX "); ::rtl::OUString aCatalog,aSchema,aTable; dbtools::qualifiedNameComponents(m_pTable->getMetaData(),m_pTable->getName(),aCatalog,aSchema,aTable,::dbtools::eInDataManipulation); ::rtl::OUString aComposedName; aComposedName = dbtools::composeTableName(m_pTable->getMetaData(),aCatalog,aSchema,aTable,sal_True,::dbtools::eInIndexDefinitions); if ( _rForName.getLength() ) { aSql.append( ::dbtools::quoteName( aQuote, _rForName ) ); aSql.appendAscii(" ON "); aSql.append(aComposedName); aSql.appendAscii(" ( "); Reference xColumnSup(descriptor,UNO_QUERY); Reference xColumns(xColumnSup->getColumns(),UNO_QUERY); Reference< XPropertySet > xColProp; sal_Bool bAddIndexAppendix = ::dbtools::getBooleanDataSourceSetting( m_pTable->getConnection(), "AddIndexAppendix" ); sal_Int32 nCount = xColumns->getCount(); for(sal_Int32 i = 0 ; i < nCount; ++i) { xColProp.set(xColumns->getByIndex(i),UNO_QUERY); aSql.append(::dbtools::quoteName( aQuote,comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME))))); if ( bAddIndexAppendix ) { aSql.appendAscii(any2bool(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISASCENDING))) ? " ASC" : " DESC"); } aSql.appendAscii(","); } aSql.setCharAt(aSql.getLength()-1,')'); } else { aSql.append(aComposedName); Reference xColumnSup(descriptor,UNO_QUERY); Reference xColumns(xColumnSup->getColumns(),UNO_QUERY); Reference< XPropertySet > xColProp; if(xColumns->getCount() != 1) throw SQLException(); xColumns->getByIndex(0) >>= xColProp; aSql.append(aDot); aSql.append(::dbtools::quoteName( aQuote,comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME))))); } Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( ); if ( xStmt.is() ) { ::rtl::OUString sSql = aSql.makeStringAndClear(); xStmt->execute(sSql); ::comphelper::disposeComponent(xStmt); } } return createObject( _rForName ); } // ------------------------------------------------------------------------- // XDrop void OIndexesHelper::dropObject(sal_Int32 /*_nPos*/,const ::rtl::OUString _sElementName) { Reference< XConnection> xConnection = m_pTable->getConnection(); if( xConnection.is() && !m_pTable->isNew()) { if ( m_pTable->getIndexService().is() ) { m_pTable->getIndexService()->dropIndex(m_pTable,_sElementName); } else { ::rtl::OUString aName,aSchema; sal_Int32 nLen = _sElementName.indexOf('.'); if(nLen != -1) aSchema = _sElementName.copy(0,nLen); aName = _sElementName.copy(nLen+1); ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("DROP INDEX "); ::rtl::OUString aComposedName = dbtools::composeTableName( m_pTable->getMetaData(), m_pTable, ::dbtools::eInIndexDefinitions, false, false, true ); ::rtl::OUString sIndexName,sTemp; sIndexName = dbtools::composeTableName( m_pTable->getMetaData(), sTemp, aSchema, aName, sal_True, ::dbtools::eInIndexDefinitions ); aSql += sIndexName + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ON ")) + aComposedName; Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( ); if ( xStmt.is() ) { xStmt->execute(aSql); ::comphelper::disposeComponent(xStmt); } } } } // -----------------------------------------------------------------------------