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