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 <com/sun/star/sdbc/XRow.hpp>
23 #include <com/sun/star/sdbc/XResultSet.hpp>
24 #include <com/sun/star/sdbc/IndexType.hpp>
25 #include <connectivity/dbtools.hxx>
26 #include <connectivity/TTableHelper.hxx>
27 #include "TConnection.hxx"
28 #include <comphelper/extract.hxx>
29 #include <rtl/ustrbuf.hxx>
30 using namespace connectivity
;
31 using namespace connectivity::sdbcx
;
32 using namespace ::com::sun::star::uno
;
33 using namespace ::com::sun::star::beans
;
34 using namespace ::com::sun::star::sdbcx
;
35 using namespace ::com::sun::star::sdbc
;
36 using namespace ::com::sun::star::container
;
37 using namespace ::com::sun::star::lang
;
41 OIndexesHelper::OIndexesHelper(OTableHelper
* _pTable
,
42 ::osl::Mutex
& _rMutex
,
43 const ::std::vector
< OUString
> &_rVector
45 : OCollection(*_pTable
,true,_rMutex
,_rVector
)
51 sdbcx::ObjectType
OIndexesHelper::createObject(const OUString
& _rName
)
53 Reference
< XConnection
> xConnection
= m_pTable
->getConnection();
54 if ( !xConnection
.is() )
57 sdbcx::ObjectType xRet
;
58 OUString aName
,aQualifier
;
59 sal_Int32 nLen
= _rName
.indexOf('.');
62 aQualifier
= _rName
.copy(0,nLen
);
63 aName
= _rName
.copy(nLen
+1);
68 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
69 OUString aSchema
,aTable
;
70 m_pTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_SCHEMANAME
)) >>= aSchema
;
71 m_pTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)) >>= aTable
;
73 Any aCatalog
= m_pTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_CATALOGNAME
));
74 Reference
< XResultSet
> xResult
= m_pTable
->getMetaData()->getIndexInfo(aCatalog
,aSchema
,aTable
,sal_False
,sal_False
);
78 Reference
< XRow
> xRow(xResult
,UNO_QUERY
);
79 while( xResult
->next() )
81 bool bUnique
= !xRow
->getBoolean(4);
82 if((aQualifier
.isEmpty() || xRow
->getString(5) == aQualifier
) && xRow
->getString(6) == aName
)
84 sal_Int32 nClustered
= xRow
->getShort(7);
85 bool bPrimarKeyIndex
= false;
90 xResult
= m_pTable
->getMetaData()->getPrimaryKeys(aCatalog
,aSchema
,aTable
);
91 xRow
.set(xResult
,UNO_QUERY
);
93 if ( xRow
.is() && xResult
->next() ) // there can be only one primary key
95 bPrimarKeyIndex
= xRow
->getString(6) == aName
;
98 catch(const Exception
&)
101 OIndexHelper
* pRet
= new OIndexHelper(m_pTable
,aName
,aQualifier
,bUnique
,
103 nClustered
== IndexType::CLUSTERED
);
113 void OIndexesHelper::impl_refresh() throw(RuntimeException
)
115 m_pTable
->refreshIndexes();
118 Reference
< XPropertySet
> OIndexesHelper::createDescriptor()
120 return new OIndexHelper(m_pTable
);
124 sdbcx::ObjectType
OIndexesHelper::appendObject( const OUString
& _rForName
, const Reference
< XPropertySet
>& descriptor
)
126 Reference
< XConnection
> xConnection
= m_pTable
->getConnection();
127 if ( !xConnection
.is() )
129 if ( m_pTable
->isNew() )
130 return cloneDescriptor( descriptor
);
132 if ( m_pTable
->getIndexService().is() )
134 m_pTable
->getIndexService()->addIndex(m_pTable
,descriptor
);
138 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
139 OUStringBuffer
aSql( "CREATE " );
140 OUString aQuote
= m_pTable
->getMetaData()->getIdentifierQuoteString( );
141 OUString
aDot( "." );
143 if(comphelper::getBOOL(descriptor
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_ISUNIQUE
))))
144 aSql
.appendAscii("UNIQUE ");
145 aSql
.appendAscii("INDEX ");
148 OUString aCatalog
,aSchema
,aTable
;
149 dbtools::qualifiedNameComponents(m_pTable
->getMetaData(),m_pTable
->getName(),aCatalog
,aSchema
,aTable
,::dbtools::eInDataManipulation
);
150 OUString aComposedName
;
152 aComposedName
= dbtools::composeTableName(m_pTable
->getMetaData(),aCatalog
,aSchema
,aTable
, true, ::dbtools::eInIndexDefinitions
);
153 if (!_rForName
.isEmpty() )
155 aSql
.append( ::dbtools::quoteName( aQuote
, _rForName
) );
156 aSql
.appendAscii(" ON ");
157 aSql
.append(aComposedName
);
158 aSql
.appendAscii(" ( ");
160 Reference
<XColumnsSupplier
> xColumnSup(descriptor
,UNO_QUERY
);
161 Reference
<XIndexAccess
> xColumns(xColumnSup
->getColumns(),UNO_QUERY
);
162 Reference
< XPropertySet
> xColProp
;
163 bool bAddIndexAppendix
= ::dbtools::getBooleanDataSourceSetting( m_pTable
->getConnection(), "AddIndexAppendix" );
164 sal_Int32 nCount
= xColumns
->getCount();
165 for(sal_Int32 i
= 0 ; i
< nCount
; ++i
)
167 xColProp
.set(xColumns
->getByIndex(i
),UNO_QUERY
);
168 aSql
.append(::dbtools::quoteName( aQuote
,comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)))));
170 if ( bAddIndexAppendix
)
173 aSql
.appendAscii(any2bool(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_ISASCENDING
)))
179 aSql
.appendAscii(",");
181 aSql
[aSql
.getLength() - 1] = ')';
185 aSql
.append(aComposedName
);
187 Reference
<XColumnsSupplier
> xColumnSup(descriptor
,UNO_QUERY
);
188 Reference
<XIndexAccess
> xColumns(xColumnSup
->getColumns(),UNO_QUERY
);
189 Reference
< XPropertySet
> xColProp
;
190 if(xColumns
->getCount() != 1)
191 throw SQLException();
193 xColumns
->getByIndex(0) >>= xColProp
;
196 aSql
.append(::dbtools::quoteName( aQuote
,comphelper::getString(xColProp
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)))));
199 Reference
< XStatement
> xStmt
= m_pTable
->getConnection()->createStatement( );
202 OUString sSql
= aSql
.makeStringAndClear();
203 xStmt
->execute(sSql
);
204 ::comphelper::disposeComponent(xStmt
);
208 return createObject( _rForName
);
212 void OIndexesHelper::dropObject(sal_Int32
/*_nPos*/,const OUString
& _sElementName
)
214 Reference
< XConnection
> xConnection
= m_pTable
->getConnection();
215 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( "DROP INDEX " );
231 OUString aComposedName
= dbtools::composeTableName( m_pTable
->getMetaData(), m_pTable
, ::dbtools::eInIndexDefinitions
, false, false, true );
232 OUString sIndexName
,sTemp
;
233 sIndexName
= dbtools::composeTableName( m_pTable
->getMetaData(), sTemp
, aSchema
, aName
, true, ::dbtools::eInIndexDefinitions
);
235 aSql
+= sIndexName
+ " ON " + aComposedName
;
237 Reference
< XStatement
> xStmt
= m_pTable
->getConnection()->createStatement( );
240 xStmt
->execute(aSql
);
241 ::comphelper::disposeComponent(xStmt
);
250 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */