Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
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;
38 : using namespace cppu;
39 :
40 :
41 3 : OIndexesHelper::OIndexesHelper(OTableHelper* _pTable,
42 : ::osl::Mutex& _rMutex,
43 : const ::std::vector< OUString> &_rVector
44 : )
45 : : OCollection(*_pTable,true,_rMutex,_rVector)
46 3 : ,m_pTable(_pTable)
47 : {
48 3 : }
49 :
50 :
51 3 : sdbcx::ObjectType OIndexesHelper::createObject(const OUString& _rName)
52 : {
53 3 : Reference< XConnection> xConnection = m_pTable->getConnection();
54 3 : if ( !xConnection.is() )
55 0 : return NULL;
56 :
57 6 : sdbcx::ObjectType xRet;
58 6 : OUString aName,aQualifier;
59 3 : sal_Int32 nLen = _rName.indexOf('.');
60 3 : if ( nLen != -1 )
61 : {
62 0 : aQualifier = _rName.copy(0,nLen);
63 0 : aName = _rName.copy(nLen+1);
64 : }
65 : else
66 3 : aName = _rName;
67 :
68 3 : ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
69 6 : OUString aSchema,aTable;
70 3 : m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= aSchema;
71 3 : m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= aTable;
72 :
73 6 : Any aCatalog = m_pTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME));
74 6 : Reference< XResultSet > xResult = m_pTable->getMetaData()->getIndexInfo(aCatalog,aSchema,aTable,sal_False,sal_False);
75 :
76 3 : if ( xResult.is() )
77 : {
78 3 : Reference< XRow > xRow(xResult,UNO_QUERY);
79 6 : while( xResult->next() )
80 : {
81 3 : bool bUnique = !xRow->getBoolean(4);
82 3 : if((aQualifier.isEmpty() || xRow->getString(5) == aQualifier ) && xRow->getString(6) == aName)
83 : {
84 3 : sal_Int32 nClustered = xRow->getShort(7);
85 3 : bool bPrimarKeyIndex = false;
86 3 : xRow.clear();
87 3 : xResult.clear();
88 : try
89 : {
90 3 : xResult = m_pTable->getMetaData()->getPrimaryKeys(aCatalog,aSchema,aTable);
91 3 : xRow.set(xResult,UNO_QUERY);
92 :
93 3 : if ( xRow.is() && xResult->next() ) // there can be only one primary key
94 : {
95 3 : bPrimarKeyIndex = xRow->getString(6) == aName;
96 : }
97 : }
98 0 : catch(const Exception&)
99 : {
100 : }
101 : OIndexHelper* pRet = new OIndexHelper(m_pTable,aName,aQualifier,bUnique,
102 : bPrimarKeyIndex,
103 3 : nClustered == IndexType::CLUSTERED);
104 3 : xRet = pRet;
105 3 : break;
106 : }
107 3 : }
108 : }
109 :
110 6 : return xRet;
111 : }
112 :
113 0 : void OIndexesHelper::impl_refresh() throw(RuntimeException)
114 : {
115 0 : m_pTable->refreshIndexes();
116 0 : }
117 :
118 0 : Reference< XPropertySet > OIndexesHelper::createDescriptor()
119 : {
120 0 : return new OIndexHelper(m_pTable);
121 : }
122 :
123 : // XAppend
124 0 : sdbcx::ObjectType OIndexesHelper::appendObject( const OUString& _rForName, const Reference< XPropertySet >& descriptor )
125 : {
126 0 : Reference< XConnection> xConnection = m_pTable->getConnection();
127 0 : if ( !xConnection.is() )
128 0 : return NULL;
129 0 : if ( m_pTable->isNew() )
130 0 : return cloneDescriptor( descriptor );
131 :
132 0 : if ( m_pTable->getIndexService().is() )
133 : {
134 0 : m_pTable->getIndexService()->addIndex(m_pTable,descriptor);
135 : }
136 : else
137 : {
138 0 : ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
139 0 : OUStringBuffer aSql( "CREATE " );
140 0 : OUString aQuote = m_pTable->getMetaData()->getIdentifierQuoteString( );
141 0 : OUString aDot( "." );
142 :
143 0 : if(comphelper::getBOOL(descriptor->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISUNIQUE))))
144 0 : aSql.appendAscii("UNIQUE ");
145 0 : aSql.appendAscii("INDEX ");
146 :
147 :
148 0 : OUString aCatalog,aSchema,aTable;
149 0 : dbtools::qualifiedNameComponents(m_pTable->getMetaData(),m_pTable->getName(),aCatalog,aSchema,aTable,::dbtools::eInDataManipulation);
150 0 : OUString aComposedName;
151 :
152 0 : aComposedName = dbtools::composeTableName(m_pTable->getMetaData(),aCatalog,aSchema,aTable, true, ::dbtools::eInIndexDefinitions);
153 0 : if (!_rForName.isEmpty() )
154 : {
155 0 : aSql.append( ::dbtools::quoteName( aQuote, _rForName ) );
156 0 : aSql.appendAscii(" ON ");
157 0 : aSql.append(aComposedName);
158 0 : aSql.appendAscii(" ( ");
159 :
160 0 : Reference<XColumnsSupplier> xColumnSup(descriptor,UNO_QUERY);
161 0 : Reference<XIndexAccess> xColumns(xColumnSup->getColumns(),UNO_QUERY);
162 0 : Reference< XPropertySet > xColProp;
163 0 : bool bAddIndexAppendix = ::dbtools::getBooleanDataSourceSetting( m_pTable->getConnection(), "AddIndexAppendix" );
164 0 : sal_Int32 nCount = xColumns->getCount();
165 0 : for(sal_Int32 i = 0 ; i < nCount; ++i)
166 : {
167 0 : xColProp.set(xColumns->getByIndex(i),UNO_QUERY);
168 0 : aSql.append(::dbtools::quoteName( aQuote,comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)))));
169 :
170 0 : if ( bAddIndexAppendix )
171 : {
172 :
173 0 : aSql.appendAscii(any2bool(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_ISASCENDING)))
174 : ?
175 : " ASC"
176 : :
177 0 : " DESC");
178 : }
179 0 : aSql.appendAscii(",");
180 : }
181 0 : aSql[aSql.getLength() - 1] = ')';
182 : }
183 : else
184 : {
185 0 : aSql.append(aComposedName);
186 :
187 0 : Reference<XColumnsSupplier> xColumnSup(descriptor,UNO_QUERY);
188 0 : Reference<XIndexAccess> xColumns(xColumnSup->getColumns(),UNO_QUERY);
189 0 : Reference< XPropertySet > xColProp;
190 0 : if(xColumns->getCount() != 1)
191 0 : throw SQLException();
192 :
193 0 : xColumns->getByIndex(0) >>= xColProp;
194 :
195 0 : aSql.append(aDot);
196 0 : aSql.append(::dbtools::quoteName( aQuote,comphelper::getString(xColProp->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)))));
197 : }
198 :
199 0 : Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( );
200 0 : if ( xStmt.is() )
201 : {
202 0 : OUString sSql = aSql.makeStringAndClear();
203 0 : xStmt->execute(sSql);
204 0 : ::comphelper::disposeComponent(xStmt);
205 0 : }
206 : }
207 :
208 0 : return createObject( _rForName );
209 : }
210 :
211 : // XDrop
212 0 : void OIndexesHelper::dropObject(sal_Int32 /*_nPos*/,const OUString& _sElementName)
213 : {
214 0 : Reference< XConnection> xConnection = m_pTable->getConnection();
215 0 : if( xConnection.is() && !m_pTable->isNew())
216 : {
217 0 : if ( m_pTable->getIndexService().is() )
218 : {
219 0 : m_pTable->getIndexService()->dropIndex(m_pTable,_sElementName);
220 : }
221 : else
222 : {
223 0 : OUString aName,aSchema;
224 0 : sal_Int32 nLen = _sElementName.indexOf('.');
225 0 : if(nLen != -1)
226 0 : aSchema = _sElementName.copy(0,nLen);
227 0 : aName = _sElementName.copy(nLen+1);
228 :
229 0 : OUString aSql( "DROP INDEX " );
230 :
231 0 : OUString aComposedName = dbtools::composeTableName( m_pTable->getMetaData(), m_pTable, ::dbtools::eInIndexDefinitions, false, false, true );
232 0 : OUString sIndexName,sTemp;
233 0 : sIndexName = dbtools::composeTableName( m_pTable->getMetaData(), sTemp, aSchema, aName, true, ::dbtools::eInIndexDefinitions );
234 :
235 0 : aSql += sIndexName + " ON " + aComposedName;
236 :
237 0 : Reference< XStatement > xStmt = m_pTable->getConnection()->createStatement( );
238 0 : if ( xStmt.is() )
239 : {
240 0 : xStmt->execute(aSql);
241 0 : ::comphelper::disposeComponent(xStmt);
242 0 : }
243 : }
244 0 : }
245 0 : }
246 :
247 :
248 :
249 :
250 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|