1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_connectivity.hxx" 30 #include "connectivity/TIndexes.hxx" 31 #include "connectivity/TIndex.hxx" 32 #include <com/sun/star/sdbc/XRow.hpp> 33 #include <com/sun/star/sdbc/XResultSet.hpp> 34 #include <com/sun/star/sdbc/IndexType.hpp> 35 #include <connectivity/dbtools.hxx> 36 #include "connectivity/TTableHelper.hxx" 37 #include "TConnection.hxx" 38 #include <comphelper/extract.hxx> 39 #include <rtl/ustrbuf.hxx> 40 using namespace connectivity; 41 using namespace connectivity::sdbcx; 42 using namespace ::com::sun::star::uno; 43 using namespace ::com::sun::star::beans; 44 using namespace ::com::sun::star::sdbcx; 45 using namespace ::com::sun::star::sdbc; 46 using namespace ::com::sun::star::container; 47 using namespace ::com::sun::star::lang; 48 using namespace cppu; 49 50 typedef connectivity::sdbcx::OCollection OCollection_TYPE; 51 // ----------------------------------------------------------------------------- 52 OIndexesHelper::OIndexesHelper(OTableHelper* _pTable, 53 ::osl::Mutex& _rMutex, 54 const ::std::vector< ::rtl::OUString> &_rVector 55 ) 56 : OCollection(*_pTable,sal_True,_rMutex,_rVector) 57 ,m_pTable(_pTable) 58 { 59 } 60 // ----------------------------------------------------------------------------- 61 62 sdbcx::ObjectType OIndexesHelper::createObject(const ::rtl::OUString& _rName) 63 { 64 Reference< XConnection> xConnection = m_pTable->getConnection(); 65 if ( !xConnection.is() ) 66 return NULL; 67 68 sdbcx::ObjectType xRet; 69 ::rtl::OUString aName,aQualifier; 70 sal_Int32 nLen = _rName.indexOf('.'); 71 if ( nLen != -1 ) 72 { 73 aQualifier = _rName.copy(0,nLen); 74 aName = _rName.copy(nLen+1); 75 } 76 else 77 aName = _rName; 78 79 ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); 80 ::rtl::OUString aSchema,aTable; 81 m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema; 82 m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable; 83 84 Any aCatalog = m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)); 85 Reference< XResultSet > xResult = m_pTable->getMetaData()->getIndexInfo(aCatalog,aSchema,aTable,sal_False,sal_False); 86 87 if ( xResult.is() ) 88 { 89 Reference< XRow > xRow(xResult,UNO_QUERY); 90 while( xResult->next() ) 91 { 92 sal_Bool bUnique = !xRow->getBoolean(4); 93 if((!aQualifier.getLength() || xRow->getString(5) == aQualifier ) && xRow->getString(6) == aName) 94 { 95 sal_Int32 nClustered = xRow->getShort(7); 96 sal_Bool bPrimarKeyIndex = sal_False; 97 xRow.clear(); 98 xResult.clear(); 99 try 100 { 101 xResult = m_pTable->getMetaData()->getPrimaryKeys(aCatalog,aSchema,aTable); 102 xRow.set(xResult,UNO_QUERY); 103 104 if ( xRow.is() && xResult->next() ) // there can be only one primary key 105 { 106 bPrimarKeyIndex = xRow->getString(6) == aName; 107 } 108 } 109 catch(Exception) 110 { 111 } 112 OIndexHelper* pRet = new OIndexHelper(m_pTable,aName,aQualifier,bUnique, 113 bPrimarKeyIndex, 114 nClustered == IndexType::CLUSTERED); 115 xRet = pRet; 116 break; 117 } 118 } 119 } 120 121 return xRet; 122 } 123 // ------------------------------------------------------------------------- 124 void OIndexesHelper::impl_refresh() throw(RuntimeException) 125 { 126 m_pTable->refreshIndexes(); 127 } 128 // ------------------------------------------------------------------------- 129 Reference< XPropertySet > OIndexesHelper::createDescriptor() 130 { 131 return new OIndexHelper(m_pTable); 132 } 133 // ------------------------------------------------------------------------- 134 // XAppend 135 sdbcx::ObjectType OIndexesHelper::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor ) 136 { 137 Reference< XConnection> xConnection = m_pTable->getConnection(); 138 if ( !xConnection.is() ) 139 return NULL; 140 if ( m_pTable->isNew() ) 141 return cloneDescriptor( descriptor ); 142 143 if ( m_pTable->getIndexService().is() ) 144 { 145 m_pTable->getIndexService()->addIndex(m_pTable,descriptor); 146 } 147 else 148 { 149 ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap(); 150 ::rtl::OUStringBuffer aSql( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CREATE "))); 151 ::rtl::OUString aQuote = m_pTable->getMetaData()->getIdentifierQuoteString( ); 152 ::rtl::OUString aDot = ::rtl::OUString::createFromAscii("."); 153 154 if(comphelper::getBOOL(descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISUNIQUE)))) 155 aSql.appendAscii("UNIQUE "); 156 aSql.appendAscii("INDEX "); 157 158 159 ::rtl::OUString aCatalog,aSchema,aTable; 160 dbtools::qualifiedNameComponents(m_pTable->getMetaData(),m_pTable->getName(),aCatalog,aSchema,aTable,::dbtools::eInDataManipulation); 161 ::rtl::OUString aComposedName; 162 163 aComposedName = dbtools::composeTableName(m_pTable->getMetaData(),aCatalog,aSchema,aTable,sal_True,::dbtools::eInIndexDefinitions); 164 if ( _rForName.getLength() ) 165 { 166 aSql.append( ::dbtools::quoteName( aQuote, _rForName ) ); 167 aSql.appendAscii(" ON "); 168 aSql.append(aComposedName); 169 aSql.appendAscii(" ( "); 170 171 Reference<XColumnsSupplier> xColumnSup(descriptor,UNO_QUERY); 172 Reference<XIndexAccess> xColumns(xColumnSup->getColumns(),UNO_QUERY); 173 Reference< XPropertySet > xColProp; 174 sal_Bool bAddIndexAppendix = ::dbtools::getBooleanDataSourceSetting( m_pTable->getConnection(), "AddIndexAppendix" ); 175 sal_Int32 nCount = xColumns->getCount(); 176 for(sal_Int32 i = 0 ; i < nCount; ++i) 177 { 178 xColProp.set(xColumns->getByIndex(i),UNO_QUERY); 179 aSql.append(::dbtools::quoteName( aQuote,comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME))))); 180 181 if ( bAddIndexAppendix ) 182 { 183 184 aSql.appendAscii(any2bool(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISASCENDING))) 185 ? 186 " ASC" 187 : 188 " DESC"); 189 } 190 aSql.appendAscii(","); 191 } 192 aSql.setCharAt(aSql.getLength()-1,')'); 193 } 194 else 195 { 196 aSql.append(aComposedName); 197 198 Reference<XColumnsSupplier> xColumnSup(descriptor,UNO_QUERY); 199 Reference<XIndexAccess> xColumns(xColumnSup->getColumns(),UNO_QUERY); 200 Reference< XPropertySet > xColProp; 201 if(xColumns->getCount() != 1) 202 throw SQLException(); 203 204 xColumns->getByIndex(0) >>= xColProp; 205 206 aSql.append(aDot); 207 aSql.append(::dbtools::quoteName( aQuote,comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME))))); 208 } 209 210 Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( ); 211 if ( xStmt.is() ) 212 { 213 ::rtl::OUString sSql = aSql.makeStringAndClear(); 214 xStmt->execute(sSql); 215 ::comphelper::disposeComponent(xStmt); 216 } 217 } 218 219 return createObject( _rForName ); 220 } 221 // ------------------------------------------------------------------------- 222 // XDrop 223 void OIndexesHelper::dropObject(sal_Int32 /*_nPos*/,const ::rtl::OUString _sElementName) 224 { 225 Reference< XConnection> xConnection = m_pTable->getConnection(); 226 if( xConnection.is() && !m_pTable->isNew()) 227 { 228 if ( m_pTable->getIndexService().is() ) 229 { 230 m_pTable->getIndexService()->dropIndex(m_pTable,_sElementName); 231 } 232 else 233 { 234 ::rtl::OUString aName,aSchema; 235 sal_Int32 nLen = _sElementName.indexOf('.'); 236 if(nLen != -1) 237 aSchema = _sElementName.copy(0,nLen); 238 aName = _sElementName.copy(nLen+1); 239 240 ::rtl::OUString aSql = ::rtl::OUString::createFromAscii("DROP INDEX "); 241 242 ::rtl::OUString aComposedName = dbtools::composeTableName( m_pTable->getMetaData(), m_pTable, ::dbtools::eInIndexDefinitions, false, false, true ); 243 ::rtl::OUString sIndexName,sTemp; 244 sIndexName = dbtools::composeTableName( m_pTable->getMetaData(), sTemp, aSchema, aName, sal_True, ::dbtools::eInIndexDefinitions ); 245 246 aSql += sIndexName 247 + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" ON ")) 248 + aComposedName; 249 250 Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( ); 251 if ( xStmt.is() ) 252 { 253 xStmt->execute(aSql); 254 ::comphelper::disposeComponent(xStmt); 255 } 256 } 257 } 258 } 259 // ----------------------------------------------------------------------------- 260 261 262 263