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>
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
;
43 OIndexesHelper::OIndexesHelper(OTableHelper
* _pTable
,
44 ::osl::Mutex
& _rMutex
,
45 const std::vector
< OUString
> &_rVector
47 : OCollection(*_pTable
,true,_rMutex
,_rVector
)
53 sdbcx::ObjectType
OIndexesHelper::createObject(const OUString
& _rName
)
55 Reference
< XConnection
> xConnection
= m_pTable
->getConnection();
56 if ( !xConnection
.is() )
59 sdbcx::ObjectType xRet
;
60 OUString aName
,aQualifier
;
61 sal_Int32 nLen
= _rName
.indexOf('.');
64 aQualifier
= _rName
.copy(0,nLen
);
65 aName
= _rName
.copy(nLen
+1);
70 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
71 OUString aSchema
,aTable
;
72 m_pTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_SCHEMANAME
)) >>= aSchema
;
73 m_pTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)) >>= aTable
;
75 Any aCatalog
= m_pTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_CATALOGNAME
));
76 Reference
< XResultSet
> xResult
= m_pTable
->getMetaData()->getIndexInfo(aCatalog
,aSchema
,aTable
,false,false);
80 Reference
< XRow
> xRow(xResult
,UNO_QUERY
);
81 while( xResult
->next() )
83 bool bUnique
= !xRow
->getBoolean(4);
84 if((aQualifier
.isEmpty() || xRow
->getString(5) == aQualifier
) && xRow
->getString(6) == aName
)
86 sal_Int32 nClustered
= xRow
->getShort(7);
87 bool bPrimarKeyIndex
= false;
92 xResult
= m_pTable
->getMetaData()->getPrimaryKeys(aCatalog
,aSchema
,aTable
);
93 xRow
.set(xResult
,UNO_QUERY
);
95 if ( xRow
.is() && xResult
->next() ) // there can be only one primary key
97 bPrimarKeyIndex
= xRow
->getString(6) == aName
;
100 catch(const Exception
&)
103 xRet
= new OIndexHelper(m_pTable
,aName
,aQualifier
,bUnique
,
105 nClustered
== IndexType::CLUSTERED
);
114 void OIndexesHelper::impl_refresh()
116 m_pTable
->refreshIndexes();
119 Reference
< XPropertySet
> OIndexesHelper::createDescriptor()
121 return new OIndexHelper(m_pTable
);
125 sdbcx::ObjectType
OIndexesHelper::appendObject( const OUString
& _rForName
, const Reference
< XPropertySet
>& descriptor
)
127 Reference
< XConnection
> xConnection
= m_pTable
->getConnection();
128 if ( !xConnection
.is() )
130 if ( m_pTable
->isNew() )
131 return cloneDescriptor( descriptor
);
133 if ( m_pTable
->getIndexService().is() )
135 m_pTable
->getIndexService()->addIndex(m_pTable
,descriptor
);
139 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
140 OUStringBuffer
aSql( "CREATE " );
141 OUString aQuote
= m_pTable
->getMetaData()->getIdentifierQuoteString( );
143 if(comphelper::getBOOL(descriptor
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_ISUNIQUE
))))
144 aSql
.append("UNIQUE ");
145 aSql
.append("INDEX ");
148 OUString aCatalog
,aSchema
,aTable
;
149 dbtools::qualifiedNameComponents(m_pTable
->getMetaData(),m_pTable
->getName(),aCatalog
,aSchema
,aTable
,::dbtools::EComposeRule::InDataManipulation
);
151 OUString aComposedName
= dbtools::composeTableName(m_pTable
->getMetaData(),aCatalog
,aSchema
,aTable
, true, ::dbtools::EComposeRule::InIndexDefinitions
);
152 if (!_rForName
.isEmpty() )
154 aSql
.append( ::dbtools::quoteName( aQuote
, _rForName
)
159 Reference
<XColumnsSupplier
> xColumnSup(descriptor
,UNO_QUERY
);
160 Reference
<XIndexAccess
> xColumns(xColumnSup
->getColumns(),UNO_QUERY
);
161 Reference
< XPropertySet
> xColProp
;
162 bool bAddIndexAppendix
= ::dbtools::getBooleanDataSourceSetting( m_pTable
->getConnection(), "AddIndexAppendix" );
163 sal_Int32 nCount
= xColumns
->getCount();
164 for(sal_Int32 i
= 0 ; i
< nCount
; ++i
)
166 xColProp
.set(xColumns
->getByIndex(i
),UNO_QUERY
);
167 aSql
.append(::dbtools::quoteName( aQuote
,comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)))));
169 if ( bAddIndexAppendix
)
172 aSql
.appendAscii(any2bool(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_ISASCENDING
)))
180 aSql
[aSql
.getLength() - 1] = ')';
184 aSql
.append(aComposedName
);
186 Reference
<XColumnsSupplier
> xColumnSup(descriptor
,UNO_QUERY
);
187 Reference
<XIndexAccess
> xColumns(xColumnSup
->getColumns(),UNO_QUERY
);
188 Reference
< XPropertySet
> xColProp
;
189 if(xColumns
->getCount() != 1)
190 throw SQLException();
192 xColumns
->getByIndex(0) >>= xColProp
;
195 + ::dbtools::quoteName( aQuote
,comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)))));
198 Reference
< XStatement
> xStmt
= m_pTable
->getConnection()->createStatement( );
201 OUString sSql
= aSql
.makeStringAndClear();
202 xStmt
->execute(sSql
);
203 ::comphelper::disposeComponent(xStmt
);
207 return createObject( _rForName
);
211 void OIndexesHelper::dropObject(sal_Int32
/*_nPos*/,const OUString
& _sElementName
)
213 Reference
< XConnection
> xConnection
= m_pTable
->getConnection();
214 if( !xConnection
.is() || m_pTable
->isNew() )
217 if ( m_pTable
->getIndexService().is() )
219 m_pTable
->getIndexService()->dropIndex(m_pTable
,_sElementName
);
223 OUString aName
,aSchema
;
224 sal_Int32 nLen
= _sElementName
.indexOf('.');
226 aSchema
= _sElementName
.copy(0,nLen
);
227 aName
= _sElementName
.copy(nLen
+1);
229 OUString
aSql( u
"DROP INDEX "_ustr
);
231 OUString aComposedName
= dbtools::composeTableName( m_pTable
->getMetaData(), m_pTable
, ::dbtools::EComposeRule::InIndexDefinitions
, true );
232 OUString sIndexName
= dbtools::composeTableName( m_pTable
->getMetaData(), OUString(), aSchema
, aName
, true, ::dbtools::EComposeRule::InIndexDefinitions
);
234 aSql
+= sIndexName
+ " ON " + aComposedName
;
236 Reference
< XStatement
> xStmt
= m_pTable
->getConnection()->createStatement( );
239 xStmt
->execute(aSql
);
240 ::comphelper::disposeComponent(xStmt
);
246 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */