1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <connectivity/TIndexes.hxx>
21 #include <connectivity/TIndex.hxx>
22 #include <connectivity/TTableHelper.hxx>
23 #include <com/sun/star/sdb/tools/XIndexAlteration.hpp>
24 #include <com/sun/star/sdbc/XRow.hpp>
25 #include <com/sun/star/sdbc/XResultSet.hpp>
26 #include <com/sun/star/sdbc/IndexType.hpp>
27 #include <com/sun/star/sdbc/SQLException.hpp>
28 #include <connectivity/dbtools.hxx>
29 #include <TConnection.hxx>
30 #include <comphelper/extract.hxx>
31 #include <comphelper/types.hxx>
32 #include <rtl/ustrbuf.hxx>
33 using namespace connectivity
;
34 using namespace connectivity::sdbcx
;
35 using namespace ::com::sun::star::uno
;
36 using namespace ::com::sun::star::beans
;
37 using namespace ::com::sun::star::sdbcx
;
38 using namespace ::com::sun::star::sdbc
;
39 using namespace ::com::sun::star::container
;
40 using namespace ::com::sun::star::lang
;
44 OIndexesHelper::OIndexesHelper(OTableHelper
* _pTable
,
45 ::osl::Mutex
& _rMutex
,
46 const std::vector
< OUString
> &_rVector
48 : OCollection(*_pTable
,true,_rMutex
,_rVector
)
54 sdbcx::ObjectType
OIndexesHelper::createObject(const OUString
& _rName
)
56 Reference
< XConnection
> xConnection
= m_pTable
->getConnection();
57 if ( !xConnection
.is() )
60 sdbcx::ObjectType xRet
;
61 OUString aName
,aQualifier
;
62 sal_Int32 nLen
= _rName
.indexOf('.');
65 aQualifier
= _rName
.copy(0,nLen
);
66 aName
= _rName
.copy(nLen
+1);
71 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
72 OUString aSchema
,aTable
;
73 m_pTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_SCHEMANAME
)) >>= aSchema
;
74 m_pTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)) >>= aTable
;
76 Any aCatalog
= m_pTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_CATALOGNAME
));
77 Reference
< XResultSet
> xResult
= m_pTable
->getMetaData()->getIndexInfo(aCatalog
,aSchema
,aTable
,false,false);
81 Reference
< XRow
> xRow(xResult
,UNO_QUERY
);
82 while( xResult
->next() )
84 bool bUnique
= !xRow
->getBoolean(4);
85 if((aQualifier
.isEmpty() || xRow
->getString(5) == aQualifier
) && xRow
->getString(6) == aName
)
87 sal_Int32 nClustered
= xRow
->getShort(7);
88 bool bPrimarKeyIndex
= false;
93 xResult
= m_pTable
->getMetaData()->getPrimaryKeys(aCatalog
,aSchema
,aTable
);
94 xRow
.set(xResult
,UNO_QUERY
);
96 if ( xRow
.is() && xResult
->next() ) // there can be only one primary key
98 bPrimarKeyIndex
= xRow
->getString(6) == aName
;
101 catch(const Exception
&)
104 OIndexHelper
* pRet
= new OIndexHelper(m_pTable
,aName
,aQualifier
,bUnique
,
106 nClustered
== IndexType::CLUSTERED
);
116 void OIndexesHelper::impl_refresh()
118 m_pTable
->refreshIndexes();
121 Reference
< XPropertySet
> OIndexesHelper::createDescriptor()
123 return new OIndexHelper(m_pTable
);
127 sdbcx::ObjectType
OIndexesHelper::appendObject( const OUString
& _rForName
, const Reference
< XPropertySet
>& descriptor
)
129 Reference
< XConnection
> xConnection
= m_pTable
->getConnection();
130 if ( !xConnection
.is() )
132 if ( m_pTable
->isNew() )
133 return cloneDescriptor( descriptor
);
135 if ( m_pTable
->getIndexService().is() )
137 m_pTable
->getIndexService()->addIndex(m_pTable
,descriptor
);
141 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
142 OUStringBuffer
aSql( "CREATE " );
143 OUString aQuote
= m_pTable
->getMetaData()->getIdentifierQuoteString( );
145 if(comphelper::getBOOL(descriptor
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_ISUNIQUE
))))
146 aSql
.append("UNIQUE ");
147 aSql
.append("INDEX ");
150 OUString aCatalog
,aSchema
,aTable
;
151 dbtools::qualifiedNameComponents(m_pTable
->getMetaData(),m_pTable
->getName(),aCatalog
,aSchema
,aTable
,::dbtools::EComposeRule::InDataManipulation
);
153 OUString aComposedName
= dbtools::composeTableName(m_pTable
->getMetaData(),aCatalog
,aSchema
,aTable
, true, ::dbtools::EComposeRule::InIndexDefinitions
);
154 if (!_rForName
.isEmpty() )
156 aSql
.append( ::dbtools::quoteName( aQuote
, _rForName
) );
158 aSql
.append(aComposedName
);
161 Reference
<XColumnsSupplier
> xColumnSup(descriptor
,UNO_QUERY
);
162 Reference
<XIndexAccess
> xColumns(xColumnSup
->getColumns(),UNO_QUERY
);
163 Reference
< XPropertySet
> xColProp
;
164 bool bAddIndexAppendix
= ::dbtools::getBooleanDataSourceSetting( m_pTable
->getConnection(), "AddIndexAppendix" );
165 sal_Int32 nCount
= xColumns
->getCount();
166 for(sal_Int32 i
= 0 ; i
< nCount
; ++i
)
168 xColProp
.set(xColumns
->getByIndex(i
),UNO_QUERY
);
169 aSql
.append(::dbtools::quoteName( aQuote
,comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)))));
171 if ( bAddIndexAppendix
)
174 aSql
.appendAscii(any2bool(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_ISASCENDING
)))
182 aSql
[aSql
.getLength() - 1] = ')';
186 aSql
.append(aComposedName
);
188 Reference
<XColumnsSupplier
> xColumnSup(descriptor
,UNO_QUERY
);
189 Reference
<XIndexAccess
> xColumns(xColumnSup
->getColumns(),UNO_QUERY
);
190 Reference
< XPropertySet
> xColProp
;
191 if(xColumns
->getCount() != 1)
192 throw SQLException();
194 xColumns
->getByIndex(0) >>= xColProp
;
197 aSql
.append(::dbtools::quoteName( aQuote
,comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)))));
200 Reference
< XStatement
> xStmt
= m_pTable
->getConnection()->createStatement( );
203 OUString sSql
= aSql
.makeStringAndClear();
204 xStmt
->execute(sSql
);
205 ::comphelper::disposeComponent(xStmt
);
209 return createObject( _rForName
);
213 void OIndexesHelper::dropObject(sal_Int32
/*_nPos*/,const OUString
& _sElementName
)
215 Reference
< XConnection
> xConnection
= m_pTable
->getConnection();
216 if( xConnection
.is() && !m_pTable
->isNew())
218 if ( m_pTable
->getIndexService().is() )
220 m_pTable
->getIndexService()->dropIndex(m_pTable
,_sElementName
);
224 OUString aName
,aSchema
;
225 sal_Int32 nLen
= _sElementName
.indexOf('.');
227 aSchema
= _sElementName
.copy(0,nLen
);
228 aName
= _sElementName
.copy(nLen
+1);
230 OUString
aSql( "DROP INDEX " );
232 OUString aComposedName
= dbtools::composeTableName( m_pTable
->getMetaData(), m_pTable
, ::dbtools::EComposeRule::InIndexDefinitions
, true );
233 OUString sIndexName
= dbtools::composeTableName( m_pTable
->getMetaData(), OUString(), aSchema
, aName
, true, ::dbtools::EComposeRule::InIndexDefinitions
);
235 aSql
+= sIndexName
+ " ON " + aComposedName
;
237 Reference
< XStatement
> xStmt
= m_pTable
->getConnection()->createStatement( );
240 xStmt
->execute(aSql
);
241 ::comphelper::disposeComponent(xStmt
);
248 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */