Coverage Report

Created: 2026-09-28 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/connectivity/source/commontools/TTableHelper.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 <sal/config.h>
21
#include <sal/log.hxx>
22
23
#include <connectivity/TTableHelper.hxx>
24
#include <com/sun/star/sdb/tools/XTableRename.hpp>
25
#include <com/sun/star/sdb/tools/XTableAlteration.hpp>
26
#include <com/sun/star/sdb/tools/XKeyAlteration.hpp>
27
#include <com/sun/star/sdb/tools/XIndexAlteration.hpp>
28
#include <sdbcx/VKey.hxx>
29
#include <com/sun/star/sdbc/XRow.hpp>
30
#include <com/sun/star/sdbc/XResultSet.hpp>
31
#include <com/sun/star/sdbcx/KeyType.hpp>
32
#include <cppuhelper/implbase.hxx>
33
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
34
#include <comphelper/types.hxx>
35
#include <connectivity/dbtools.hxx>
36
#include <connectivity/sdbcx/VCollection.hxx>
37
#include <unotools/sharedunocomponent.hxx>
38
#include <TConnection.hxx>
39
40
#include <o3tl/functional.hxx>
41
42
#include <iterator>
43
#include <set>
44
45
using namespace ::comphelper;
46
using namespace connectivity;
47
using namespace ::com::sun::star::uno;
48
using namespace ::com::sun::star::beans;
49
using namespace ::com::sun::star::sdbcx;
50
using namespace ::com::sun::star::sdbc;
51
using namespace ::com::sun::star::container;
52
using namespace ::com::sun::star::lang;
53
54
namespace
55
{
56
    /// helper class for column property change events which holds the OComponentDefinition weak
57
class OTableContainerListener:
58
    public ::cppu::WeakImplHelper< XContainerListener >
59
{
60
    OTableHelper* m_pComponent;
61
    std::map< OUString,bool> m_aRefNames;
62
63
protected:
64
0
    virtual ~OTableContainerListener() override {}
65
public:
66
0
    explicit OTableContainerListener(OTableHelper* _pComponent) : m_pComponent(_pComponent){}
67
    // noncopyable
68
    OTableContainerListener(const OTableContainerListener&) = delete;
69
    const OTableContainerListener& operator=(const OTableContainerListener&) = delete;
70
    virtual void SAL_CALL elementInserted( const css::container::ContainerEvent& /*Event*/ ) override
71
0
    {
72
0
    }
73
    virtual void SAL_CALL elementRemoved( const css::container::ContainerEvent& Event ) override
74
0
    {
75
        // tdf#137745, perhaps connectivity::OTableHelper::disposing() has been called
76
        // which called OTableContainerListener::clear(), so m_pComponent may be null
77
0
        if (m_pComponent == nullptr)
78
0
            return;
79
80
0
        OUString sName;
81
0
        Event.Accessor  >>= sName;
82
0
        if ( m_aRefNames.contains(sName) )
83
0
            m_pComponent->refreshKeys();
84
0
    }
85
    virtual void SAL_CALL elementReplaced( const css::container::ContainerEvent& Event ) override
86
0
    {
87
0
        OUString sOldComposedName,sNewComposedName;
88
0
        Event.ReplacedElement   >>= sOldComposedName;
89
0
        Event.Accessor          >>= sNewComposedName;
90
0
        if ( sOldComposedName != sNewComposedName && m_aRefNames.contains(sOldComposedName) )
91
0
            m_pComponent->refreshKeys();
92
0
    }
93
    // XEventListener
94
    virtual void SAL_CALL disposing( const EventObject& /*_rSource*/ ) override
95
0
    {
96
0
    }
97
0
    void clear() { m_pComponent = nullptr; }
98
0
    void add(const OUString& _sRefName) { m_aRefNames.emplace(_sRefName,true); }
99
};
100
}
101
namespace connectivity
102
{
103
    static OUString lcl_getServiceNameForSetting(const Reference< css::sdbc::XConnection >& _xConnection,const OUString& i_sSetting)
104
0
    {
105
0
        OUString sSupportService;
106
0
        Any aValue;
107
0
        if ( ::dbtools::getDataSourceSetting(_xConnection,i_sSetting,aValue) )
108
0
        {
109
0
            aValue >>= sSupportService;
110
0
        }
111
0
        return sSupportService;
112
0
    }
113
    struct OTableHelperImpl
114
    {
115
        TKeyMap  m_aKeys;
116
        // helper services which can be provided by extensions
117
        Reference< css::sdb::tools::XTableRename>      m_xRename;
118
        Reference< css::sdb::tools::XTableAlteration>  m_xAlter;
119
        Reference< css::sdb::tools::XKeyAlteration>    m_xKeyAlter;
120
        Reference< css::sdb::tools::XIndexAlteration>  m_xIndexAlter;
121
122
        Reference< css::sdbc::XDatabaseMetaData >      m_xMetaData;
123
        Reference< css::sdbc::XConnection >            m_xConnection;
124
        rtl::Reference<OTableContainerListener>        m_xTablePropertyListener;
125
        std::vector< ColumnDesc >                    m_aColumnDesc;
126
        explicit OTableHelperImpl(const Reference< css::sdbc::XConnection >& _xConnection)
127
0
            : m_xConnection(_xConnection)
128
0
        {
129
0
            try
130
0
            {
131
0
                m_xMetaData = m_xConnection->getMetaData();
132
0
                Reference<XMultiServiceFactory> xFac(_xConnection,UNO_QUERY);
133
0
                if ( xFac.is() )
134
0
                {
135
0
                    m_xRename.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,u"TableRenameServiceName"_ustr)),UNO_QUERY);
136
0
                    m_xAlter.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,u"TableAlterationServiceName"_ustr)),UNO_QUERY);
137
0
                    m_xKeyAlter.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,u"KeyAlterationServiceName"_ustr)),UNO_QUERY);
138
0
                    m_xIndexAlter.set(xFac->createInstance(lcl_getServiceNameForSetting(m_xConnection,u"IndexAlterationServiceName"_ustr)),UNO_QUERY);
139
0
                }
140
0
            }
141
0
            catch(const Exception&)
142
0
            {
143
0
            }
144
0
        }
145
    };
146
}
147
148
OTableHelper::OTableHelper( sdbcx::OCollection* _pTables,
149
                           const Reference< XConnection >& _xConnection,
150
                           bool _bCase)
151
0
    :OTable_TYPEDEF(_pTables,_bCase)
152
0
    ,m_pImpl(new OTableHelperImpl(_xConnection))
153
0
{
154
0
}
155
156
OTableHelper::OTableHelper( sdbcx::OCollection* _pTables,
157
                            const Reference< XConnection >& _xConnection,
158
                            bool _bCase,
159
                            const OUString& Name,
160
                            const OUString& Type,
161
                            const OUString& Description ,
162
                            const OUString& SchemaName,
163
                            const OUString& CatalogName
164
0
                        ) : OTable_TYPEDEF(_pTables,
165
0
                                            _bCase,
166
0
                                            Name,
167
0
                                          Type,
168
0
                                          Description,
169
0
                                          SchemaName,
170
0
                                          CatalogName)
171
0
                        ,m_pImpl(new OTableHelperImpl(_xConnection))
172
0
{
173
0
}
174
175
OTableHelper::~OTableHelper()
176
0
{
177
0
}
178
179
void SAL_CALL OTableHelper::disposing()
180
0
{
181
0
    ::osl::MutexGuard aGuard(m_aMutex);
182
0
    if ( m_pImpl->m_xTablePropertyListener.is() )
183
0
    {
184
0
        m_pTables->removeContainerListener(m_pImpl->m_xTablePropertyListener);
185
0
        m_pImpl->m_xTablePropertyListener->clear();
186
0
        m_pImpl->m_xTablePropertyListener.clear();
187
0
    }
188
0
    OTable_TYPEDEF::disposing();
189
190
0
    m_pImpl->m_xConnection  = nullptr;
191
0
    m_pImpl->m_xMetaData    = nullptr;
192
193
0
}
194
195
196
namespace
197
{
198
    /** collects ColumnDesc's from a resultset produced by XDatabaseMetaData::getColumns
199
    */
200
    void lcl_collectColumnDescs_throw( const Reference< XResultSet >& _rxResult, std::vector< ColumnDesc >& _out_rColumns )
201
0
    {
202
0
        Reference< XRow > xRow( _rxResult, UNO_QUERY_THROW );
203
0
        while ( _rxResult->next() )
204
0
        {
205
            // tdf#162227: ODBC SQLGetData requires that data must be retrieved in increasing
206
            // column number order, unless the driver supports SQL_GD_ANY_ORDER extension (see
207
            // https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlgetdata-function).
208
            // We can't emplace_back(getString(4), getInt(5), ..., getString(12), getInt(17)),
209
            // because MSVC would reorder calls into getInt(17) -> getString(12) -> ..., and then
210
            // MS SQL Server ODBC driver will give error on access of column 12 after column 17.
211
0
            OUString sName = xRow->getString(4); // COLUMN_NAME
212
0
            sal_Int32 nField5 = xRow->getInt(5);
213
0
            OUString aField6 = xRow->getString(6);
214
0
            sal_Int32 nField7 = xRow->getInt(7);
215
0
            sal_Int32 nField9 = xRow->getInt(9);
216
0
            sal_Int32 nField11 = xRow->getInt(11);
217
0
            OUString sField12 = xRow->getString(12);
218
0
            OUString sField13 = xRow->getString(13);
219
0
            OrdinalPosition nOrdinalPosition = xRow->getInt(17); // ORDINAL_POSITION
220
0
            _out_rColumns.emplace_back(sName, nField5, aField6, nField7, nField9, nField11,
221
0
                                       sField12, sField13, nOrdinalPosition);
222
0
        }
223
0
    }
224
225
    /** checks a given array of ColumnDesc's whether it has reasonable ordinal positions. If not,
226
        they will be normalized to be the array index.
227
    */
228
    void lcl_sanitizeColumnDescs( std::vector< ColumnDesc >& _rColumns )
229
0
    {
230
0
        if ( _rColumns.empty() )
231
0
            return;
232
233
        // collect all used ordinals
234
0
        std::set< OrdinalPosition > aUsedOrdinals;
235
0
        for ( const auto& collect : _rColumns )
236
0
            aUsedOrdinals.insert( collect.nOrdinalPosition );
237
238
        // we need to have as much different ordinals as we have different columns
239
0
        bool bDuplicates = aUsedOrdinals.size() != _rColumns.size();
240
        // and it needs to be a continuous range
241
0
        size_t nOrdinalsRange = *aUsedOrdinals.rbegin() - *aUsedOrdinals.begin() + 1;
242
0
        bool bGaps = nOrdinalsRange != _rColumns.size();
243
244
        // if that's not the case, normalize it
245
0
        if ( bGaps || bDuplicates )
246
0
        {
247
0
            OSL_FAIL( "lcl_sanitizeColumnDescs: database did provide invalid ORDINAL_POSITION values!" );
248
249
0
            OrdinalPosition nNormalizedPosition = 1;
250
0
            for ( auto& normalize : _rColumns )
251
0
                normalize.nOrdinalPosition = nNormalizedPosition++;
252
0
            return;
253
0
        }
254
255
        // what's left is that the range might not be from 1 to <column count>, but for instance
256
        // 0 to <column count>-1.
257
0
        size_t nOffset = *aUsedOrdinals.begin() - 1;
258
0
        for ( auto& offset : _rColumns )
259
0
            offset.nOrdinalPosition -= nOffset;
260
0
    }
261
}
262
263
264
void OTableHelper::refreshColumns()
265
0
{
266
0
    ::std::vector< OUString> aVector;
267
0
    if(!isNew())
268
0
    {
269
0
        Any aCatalog;
270
0
        if ( !m_CatalogName.isEmpty() )
271
0
            aCatalog <<= m_CatalogName;
272
273
0
        ::utl::SharedUNOComponent< XResultSet > xResult( getMetaData()->getColumns(
274
0
            aCatalog,
275
0
            m_SchemaName,
276
0
            m_Name,
277
0
            u"%"_ustr
278
0
        ) );
279
280
        // collect the column names, together with their ordinal position
281
0
        m_pImpl->m_aColumnDesc.clear();
282
0
        lcl_collectColumnDescs_throw( xResult, m_pImpl->m_aColumnDesc );
283
284
        // ensure that the ordinal positions as obtained from the meta data do make sense
285
0
        lcl_sanitizeColumnDescs( m_pImpl->m_aColumnDesc );
286
287
        // sort by ordinal position
288
0
        std::map< OrdinalPosition, OUString > aSortedColumns;
289
0
        for (const auto& copy : m_pImpl->m_aColumnDesc)
290
0
            aSortedColumns[ copy.nOrdinalPosition ] = copy.sName;
291
292
        // copy them to aVector, now that we have the proper ordering
293
0
        std::transform(
294
0
            aSortedColumns.begin(),
295
0
            aSortedColumns.end(),
296
0
            std::insert_iterator< ::std::vector< OUString> >( aVector, aVector.begin() ),
297
0
            ::o3tl::select2nd< std::map< OrdinalPosition, OUString >::value_type >()
298
0
            );
299
0
    }
300
301
0
    if(m_xColumns)
302
0
        m_xColumns->reFill(aVector);
303
0
    else
304
0
        m_xColumns.reset(createColumns(aVector));
305
0
}
306
307
const ColumnDesc* OTableHelper::getColumnDescription(const OUString& _sName) const
308
0
{
309
0
    const ColumnDesc* pRet = nullptr;
310
0
    auto aIter = std::find_if(m_pImpl->m_aColumnDesc.begin(), m_pImpl->m_aColumnDesc.end(),
311
0
        [&_sName](const ColumnDesc& rColumnDesc) { return rColumnDesc.sName == _sName; });
312
0
    if (aIter != m_pImpl->m_aColumnDesc.end())
313
0
        pRet = &*aIter;
314
0
    return pRet;
315
0
}
316
317
void OTableHelper::refreshPrimaryKeys(::std::vector< OUString>& _rNames)
318
0
{
319
0
    Any aCatalog;
320
0
    if ( !m_CatalogName.isEmpty() )
321
0
        aCatalog <<= m_CatalogName;
322
0
    Reference< XResultSet > xResult = getMetaData()->getPrimaryKeys(aCatalog,m_SchemaName,m_Name);
323
324
0
    if ( xResult.is() )
325
0
    {
326
0
        auto pKeyProps = std::make_shared<sdbcx::KeyProperties>(OUString(),KeyType::PRIMARY,0,0);
327
0
        OUString aPkName;
328
0
        bool bAlreadyFetched = false;
329
0
        const Reference< XRow > xRow(xResult,UNO_QUERY);
330
0
        while ( xResult->next() )
331
0
        {
332
0
            pKeyProps->m_aKeyColumnNames.push_back(xRow->getString(4));
333
0
            if ( !bAlreadyFetched )
334
0
            {
335
0
                aPkName = xRow->getString(6);
336
0
                SAL_WARN_IF(xRow->wasNull(),"connectivity.commontools", "NULL Primary Key name");
337
0
                SAL_WARN_IF(aPkName.isEmpty(),"connectivity.commontools", "empty Primary Key name");
338
0
                bAlreadyFetched = true;
339
0
            }
340
0
        }
341
342
0
        if(bAlreadyFetched)
343
0
        {
344
0
            SAL_WARN_IF(aPkName.isEmpty(),"connectivity.commontools", "empty Primary Key name");
345
0
            SAL_WARN_IF(pKeyProps->m_aKeyColumnNames.empty(),"connectivity.commontools", "Primary Key has no columns");
346
0
            m_pImpl->m_aKeys.emplace(aPkName,pKeyProps);
347
0
            _rNames.push_back(aPkName);
348
0
        }
349
0
    } // if ( xResult.is() && xResult->next() )
350
0
    ::comphelper::disposeComponent(xResult);
351
0
}
352
353
void OTableHelper::refreshForeignKeys(::std::vector< OUString>& _rNames)
354
0
{
355
0
    Any aCatalog;
356
0
    if ( !m_CatalogName.isEmpty() )
357
0
        aCatalog <<= m_CatalogName;
358
0
    Reference< XResultSet > xResult = getMetaData()->getImportedKeys(aCatalog,m_SchemaName,m_Name);
359
0
    Reference< XRow > xRow(xResult,UNO_QUERY);
360
361
0
    if ( !xRow.is() )
362
0
        return;
363
364
0
    std::shared_ptr<sdbcx::KeyProperties> pKeyProps;
365
0
    OUString aName,sCatalog,aSchema,sOldFKName;
366
0
    while( xResult->next() )
367
0
    {
368
        // this must be outside the "if" because we have to call in a right order
369
0
        sCatalog    = xRow->getString(1);
370
0
        if ( xRow->wasNull() )
371
0
            sCatalog.clear();
372
0
        aSchema     = xRow->getString(2);
373
0
        aName       = xRow->getString(3);
374
375
0
        const OUString sForeignKeyColumn = xRow->getString(8);
376
0
        const sal_Int32 nUpdateRule = xRow->getInt(10);
377
0
        const sal_Int32 nDeleteRule = xRow->getInt(11);
378
0
        const OUString sFkName = xRow->getString(12);
379
380
0
        if ( !sFkName.isEmpty() && !xRow->wasNull() )
381
0
        {
382
0
            if ( sOldFKName != sFkName )
383
0
            {
384
0
                if ( pKeyProps )
385
0
                    m_pImpl->m_aKeys.emplace(sOldFKName,pKeyProps);
386
387
0
                const OUString sReferencedName = ::dbtools::composeTableName(getMetaData(),sCatalog,aSchema,aName,false,::dbtools::EComposeRule::InDataManipulation);
388
0
                pKeyProps = std::make_shared<sdbcx::KeyProperties>(sReferencedName,KeyType::FOREIGN,nUpdateRule,nDeleteRule);
389
0
                pKeyProps->m_aKeyColumnNames.push_back(sForeignKeyColumn);
390
0
                _rNames.push_back(sFkName);
391
0
                if ( m_pTables->hasByName(sReferencedName) )
392
0
                {
393
0
                    if ( !m_pImpl->m_xTablePropertyListener.is() )
394
0
                        m_pImpl->m_xTablePropertyListener = new OTableContainerListener(this);
395
0
                    m_pTables->addContainerListener(m_pImpl->m_xTablePropertyListener);
396
0
                    m_pImpl->m_xTablePropertyListener->add(sReferencedName);
397
0
                } // if ( m_pTables->hasByName(sReferencedName) )
398
0
                sOldFKName = sFkName;
399
0
            } // if ( sOldFKName != sFkName )
400
0
            else if ( pKeyProps )
401
0
            {
402
0
                pKeyProps->m_aKeyColumnNames.push_back(sForeignKeyColumn);
403
0
            }
404
0
        }
405
0
    } // while( xResult->next() )
406
0
    if ( pKeyProps )
407
0
        m_pImpl->m_aKeys.emplace(sOldFKName,pKeyProps);
408
0
    ::comphelper::disposeComponent(xResult);
409
0
}
410
411
void OTableHelper::refreshKeys()
412
0
{
413
0
    m_pImpl->m_aKeys.clear();
414
415
0
    ::std::vector< OUString> aNames;
416
417
0
    if(!isNew())
418
0
    {
419
0
        refreshPrimaryKeys(aNames);
420
0
        refreshForeignKeys(aNames);
421
0
        m_xKeys.reset(createKeys(aNames));
422
0
    } // if(!isNew())
423
0
    else if (!m_xKeys )
424
0
        m_xKeys.reset(createKeys(aNames));
425
    /*if(m_pKeys)
426
        m_pKeys->reFill(aVector);
427
    else*/
428
429
0
}
430
431
void OTableHelper::refreshIndexes()
432
0
{
433
0
    ::std::vector< OUString> aVector;
434
0
    if(!isNew())
435
0
    {
436
        // fill indexes
437
0
        Any aCatalog;
438
0
        if ( !m_CatalogName.isEmpty() )
439
0
            aCatalog <<= m_CatalogName;
440
0
        Reference< XResultSet > xResult = getMetaData()->getIndexInfo(aCatalog,m_SchemaName,m_Name,false,false);
441
442
0
        if(xResult.is())
443
0
        {
444
0
            Reference< XRow > xRow(xResult,UNO_QUERY);
445
0
            OUString sCatalogSep = getMetaData()->getCatalogSeparator();
446
0
            OUString sPreviousRoundName;
447
0
            while( xResult->next() )
448
0
            {
449
0
                OUString aName = xRow->getString(5);
450
0
                if(!aName.isEmpty())
451
0
                    aName += sCatalogSep;
452
0
                aName += xRow->getString(6);
453
0
                if ( !aName.isEmpty() )
454
0
                {
455
                    // don't insert the name if the last one we inserted was the same
456
0
                    if (sPreviousRoundName != aName)
457
0
                        aVector.push_back(aName);
458
0
                }
459
0
                sPreviousRoundName = aName;
460
0
            }
461
0
            ::comphelper::disposeComponent(xResult);
462
0
        }
463
0
    }
464
465
0
    if(m_xIndexes)
466
0
        m_xIndexes->reFill(aVector);
467
0
    else
468
0
        m_xIndexes.reset(createIndexes(aVector));
469
0
}
470
471
OUString OTableHelper::getRenameStart() const
472
0
{
473
0
    OUString sSql(u"RENAME "_ustr);
474
0
    if ( m_Type == "VIEW" )
475
0
        sSql += " VIEW ";
476
0
    else
477
0
        sSql += " TABLE ";
478
479
0
    return sSql;
480
0
}
481
482
// XRename
483
void SAL_CALL OTableHelper::rename( const OUString& newName )
484
0
{
485
0
    ::osl::MutexGuard aGuard(m_aMutex);
486
0
    checkDisposed(
487
0
#ifdef __GNUC__
488
0
        ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
489
#else
490
        rBHelper.bDisposed
491
#endif
492
0
        );
493
494
0
    if(!isNew())
495
0
    {
496
0
        if ( m_pImpl->m_xRename.is() )
497
0
        {
498
0
            m_pImpl->m_xRename->rename(this,newName);
499
0
        }
500
0
        else
501
0
        {
502
0
            OUString sSql = getRenameStart();
503
504
0
            OUString sCatalog,sSchema,sTable;
505
0
            ::dbtools::qualifiedNameComponents(getMetaData(),newName,sCatalog,sSchema,sTable,::dbtools::EComposeRule::InDataManipulation);
506
507
0
            OUString sComposedName;
508
0
            sComposedName = ::dbtools::composeTableName(getMetaData(),m_CatalogName,m_SchemaName,m_Name,true,::dbtools::EComposeRule::InDataManipulation);
509
0
            sSql += sComposedName
510
0
                 + " TO ";
511
0
            sComposedName = ::dbtools::composeTableName(getMetaData(),sCatalog,sSchema,sTable,true,::dbtools::EComposeRule::InDataManipulation);
512
0
            sSql += sComposedName;
513
514
0
            Reference< XStatement > xStmt = m_pImpl->m_xConnection->createStatement(  );
515
0
            if ( xStmt.is() )
516
0
            {
517
0
                xStmt->execute(sSql);
518
0
                ::comphelper::disposeComponent(xStmt);
519
0
            }
520
0
        }
521
522
0
        OTable_TYPEDEF::rename(newName);
523
0
    }
524
0
    else
525
0
        ::dbtools::qualifiedNameComponents(getMetaData(),newName,m_CatalogName,m_SchemaName,m_Name,::dbtools::EComposeRule::InTableDefinitions);
526
0
}
527
528
Reference< XDatabaseMetaData> OTableHelper::getMetaData() const
529
0
{
530
0
    return m_pImpl->m_xMetaData;
531
0
}
532
533
void SAL_CALL OTableHelper::alterColumnByIndex( sal_Int32 index, const Reference< XPropertySet >& descriptor )
534
0
{
535
0
    ::osl::MutexGuard aGuard(m_aMutex);
536
0
    checkDisposed(
537
0
#ifdef __GNUC__
538
0
        ::connectivity::sdbcx::OTableDescriptor_BASE::rBHelper.bDisposed
539
#else
540
        rBHelper.bDisposed
541
#endif
542
0
        );
543
544
0
    Reference< XPropertySet > xOld(
545
0
        m_xColumns->getByIndex(index), css::uno::UNO_QUERY);
546
0
    if(xOld.is())
547
0
        alterColumnByName(getString(xOld->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME))),descriptor);
548
0
}
549
550
551
OUString SAL_CALL OTableHelper::getName()
552
0
{
553
0
    OUString sComposedName = ::dbtools::composeTableName(getMetaData(),m_CatalogName,m_SchemaName,m_Name,false,::dbtools::EComposeRule::InDataManipulation);
554
0
    return sComposedName;
555
0
}
556
557
const OUString & OTableHelper::getTableName()
558
0
{
559
0
    return m_Name;
560
0
}
561
562
std::shared_ptr<sdbcx::KeyProperties> OTableHelper::getKeyProperties(const OUString& _sName) const
563
0
{
564
0
    std::shared_ptr<sdbcx::KeyProperties> pKeyProps;
565
0
    TKeyMap::const_iterator aFind = m_pImpl->m_aKeys.find(_sName);
566
0
    if ( aFind != m_pImpl->m_aKeys.end() )
567
0
    {
568
0
        pKeyProps = aFind->second;
569
0
    }
570
0
    else // only a fall back
571
0
    {
572
0
        OSL_FAIL("No key with the given name found");
573
0
        pKeyProps = std::make_shared<sdbcx::KeyProperties>();
574
0
    }
575
576
0
    return pKeyProps;
577
0
}
578
579
void OTableHelper::addKey(const OUString& _sName,const std::shared_ptr<sdbcx::KeyProperties>& _aKeyProperties)
580
0
{
581
0
    m_pImpl->m_aKeys.emplace(_sName,_aKeyProperties);
582
0
}
583
584
OUString OTableHelper::getTypeCreatePattern() const
585
0
{
586
0
    return OUString();
587
0
}
588
589
Reference< XConnection> const & OTableHelper::getConnection() const
590
0
{
591
0
    return m_pImpl->m_xConnection;
592
0
}
593
594
Reference< css::sdb::tools::XTableRename> const & OTableHelper::getRenameService() const
595
0
{
596
0
    return m_pImpl->m_xRename;
597
0
}
598
599
Reference< css::sdb::tools::XTableAlteration> const & OTableHelper::getAlterService() const
600
0
{
601
0
    return m_pImpl->m_xAlter;
602
0
}
603
604
Reference< css::sdb::tools::XKeyAlteration> const & OTableHelper::getKeyService() const
605
0
{
606
0
    return m_pImpl->m_xKeyAlter;
607
0
}
608
609
Reference< css::sdb::tools::XIndexAlteration> const & OTableHelper::getIndexService() const
610
0
{
611
0
    return m_pImpl->m_xIndexAlter;
612
0
}
613
614
615
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */