Coverage Report

Created: 2025-11-16 09:57

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