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 <string.h>
21 
22 #include <TableDeco.hxx>
23 #include <definitioncolumn.hxx>
24 #include <stringconstants.hxx>
25 #include <core_resource.hxx>
26 #include <strings.hrc>
27 #include <osl/diagnose.h>
28 #include <sal/log.hxx>
29 
30 #include <cppuhelper/typeprovider.hxx>
31 #include <comphelper/property.hxx>
32 #include <comphelper/servicehelper.hxx>
33 #include <comphelper/types.hxx>
34 #include <com/sun/star/util/XRefreshListener.hpp>
35 #include <com/sun/star/sdbc/SQLException.hpp>
36 #include <com/sun/star/sdbc/XConnection.hpp>
37 #include <com/sun/star/sdbc/XRow.hpp>
38 #include <com/sun/star/sdbcx/Privilege.hpp>
39 #include <com/sun/star/beans/PropertyAttribute.hpp>
40 #include <connectivity/dbtools.hxx>
41 #include <connectivity/dbexception.hxx>
42 #include <ContainerMediator.hxx>
43 
44 using namespace dbaccess;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::util;
47 using namespace ::com::sun::star::lang;
48 using namespace ::com::sun::star::beans;
49 using namespace ::com::sun::star::sdbc;
50 using namespace ::com::sun::star::sdbcx;
51 using namespace ::com::sun::star::container;
52 using namespace ::osl;
53 using namespace ::comphelper;
54 using namespace ::dbtools;
55 using namespace ::cppu;
56 
57 // ODBTableDecorator
58 
ODBTableDecorator(const Reference<XConnection> & _rxConnection,const Reference<XColumnsSupplier> & _rxNewTable,const Reference<XNumberFormatsSupplier> & _rxNumberFormats,const Reference<XNameAccess> & _xColumnDefinitions)59 ODBTableDecorator::ODBTableDecorator( const Reference< XConnection >& _rxConnection, const Reference< XColumnsSupplier >& _rxNewTable,
60         const Reference< XNumberFormatsSupplier >& _rxNumberFormats, const Reference< XNameAccess >& _xColumnDefinitions )
61     :OTableDescriptor_BASE(m_aMutex)
62     ,ODataSettings(OTableDescriptor_BASE::rBHelper)
63     ,m_xTable(_rxNewTable)
64     ,m_xColumnDefinitions(_xColumnDefinitions)
65     ,m_xConnection( _rxConnection )
66     ,m_xMetaData( _rxConnection.is() ? _rxConnection->getMetaData() : Reference< XDatabaseMetaData >() )
67     ,m_xNumberFormats( _rxNumberFormats )
68     ,m_nPrivileges(-1)
69 {
70     ODataSettings::registerPropertiesFor(this);
71 }
72 
~ODBTableDecorator()73 ODBTableDecorator::~ODBTableDecorator()
74 {
75 }
76 
getImplementationId()77 Sequence< sal_Int8 > ODBTableDecorator::getImplementationId()
78 {
79     return css::uno::Sequence<sal_Int8>();
80 }
81 
82 // OComponentHelper
disposing()83 void SAL_CALL ODBTableDecorator::disposing()
84 {
85     OPropertySetHelper::disposing();
86     OTableDescriptor_BASE::disposing();
87 
88     MutexGuard aGuard(m_aMutex);
89     m_xTable        = nullptr;
90     m_xMetaData     = nullptr;
91     m_xColumnDefinitions = nullptr;
92     m_xNumberFormats = nullptr;
93     if ( m_pColumns )
94         m_pColumns->disposing();
95     m_xColumnMediator = nullptr;
96 }
97 
convertFastPropertyValue(Any & rConvertedValue,Any & rOldValue,sal_Int32 nHandle,const Any & rValue)98 sal_Bool SAL_CALL ODBTableDecorator::convertFastPropertyValue(
99                             Any & rConvertedValue,
100                             Any & rOldValue,
101                             sal_Int32 nHandle,
102                             const Any& rValue )
103 {
104     bool bRet = true;
105     switch(nHandle)
106     {
107         case PROPERTY_ID_PRIVILEGES:
108         case PROPERTY_ID_FILTER:
109         case PROPERTY_ID_ORDER:
110         case PROPERTY_ID_APPLYFILTER:
111         case PROPERTY_ID_FONT:
112         case PROPERTY_ID_ROW_HEIGHT:
113         case PROPERTY_ID_AUTOGROW:
114         case PROPERTY_ID_TEXTCOLOR:
115         case PROPERTY_ID_TEXTLINECOLOR:
116         case PROPERTY_ID_TEXTEMPHASIS:
117         case PROPERTY_ID_TEXTRELIEF:
118         case PROPERTY_ID_FONTCHARWIDTH:
119         case PROPERTY_ID_FONTCHARSET:
120         case PROPERTY_ID_FONTFAMILY:
121         case PROPERTY_ID_FONTHEIGHT:
122         case PROPERTY_ID_FONTKERNING:
123         case PROPERTY_ID_FONTNAME:
124         case PROPERTY_ID_FONTORIENTATION:
125         case PROPERTY_ID_FONTPITCH:
126         case PROPERTY_ID_FONTSLANT:
127         case PROPERTY_ID_FONTSTRIKEOUT:
128         case PROPERTY_ID_FONTSTYLENAME:
129         case PROPERTY_ID_FONTUNDERLINE:
130         case PROPERTY_ID_FONTWEIGHT:
131         case PROPERTY_ID_FONTWIDTH:
132         case PROPERTY_ID_FONTWORDLINEMODE:
133         case PROPERTY_ID_FONTTYPE:
134             bRet = ODataSettings::convertFastPropertyValue(rConvertedValue, rOldValue,nHandle,rValue);
135             break;
136 
137         default:
138             {
139                 Any aValue;
140                 getFastPropertyValue(aValue,nHandle);
141                 bRet = ::comphelper::tryPropertyValue(rConvertedValue,rOldValue,rValue,aValue,::cppu::UnoType<OUString>::get());
142             }
143             break; // we assume that it works
144     }
145     return bRet;
146 }
147 
setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle,const Any & _rValue)148 void ODBTableDecorator::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue)
149 {
150     switch(_nHandle)
151     {
152         case PROPERTY_ID_PRIVILEGES:
153             SAL_WARN("dbaccess", "Property is readonly!");
154             [[fallthrough]];
155         case PROPERTY_ID_FILTER:
156         case PROPERTY_ID_ORDER:
157         case PROPERTY_ID_APPLYFILTER:
158         case PROPERTY_ID_FONT:
159         case PROPERTY_ID_ROW_HEIGHT:
160         case PROPERTY_ID_AUTOGROW:
161         case PROPERTY_ID_TEXTCOLOR:
162         case PROPERTY_ID_TEXTLINECOLOR:
163         case PROPERTY_ID_TEXTEMPHASIS:
164         case PROPERTY_ID_TEXTRELIEF:
165         case PROPERTY_ID_FONTCHARWIDTH:
166         case PROPERTY_ID_FONTCHARSET:
167         case PROPERTY_ID_FONTFAMILY:
168         case PROPERTY_ID_FONTHEIGHT:
169         case PROPERTY_ID_FONTKERNING:
170         case PROPERTY_ID_FONTNAME:
171         case PROPERTY_ID_FONTORIENTATION:
172         case PROPERTY_ID_FONTPITCH:
173         case PROPERTY_ID_FONTSLANT:
174         case PROPERTY_ID_FONTSTRIKEOUT:
175         case PROPERTY_ID_FONTSTYLENAME:
176         case PROPERTY_ID_FONTUNDERLINE:
177         case PROPERTY_ID_FONTWEIGHT:
178         case PROPERTY_ID_FONTWIDTH:
179         case PROPERTY_ID_FONTWORDLINEMODE:
180         case PROPERTY_ID_FONTTYPE:
181 
182             ODataSettings::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
183             break;
184         case PROPERTY_ID_CATALOGNAME:
185             {
186                 Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
187                 xProp->setPropertyValue(PROPERTY_CATALOGNAME,_rValue);
188             }
189             break;
190         case PROPERTY_ID_SCHEMANAME:
191             {
192                 Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
193                 xProp->setPropertyValue(PROPERTY_SCHEMANAME,_rValue);
194             }
195             break;
196         case PROPERTY_ID_NAME:
197             {
198                 Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
199                 xProp->setPropertyValue(PROPERTY_NAME,_rValue);
200             }
201             break;
202         case PROPERTY_ID_DESCRIPTION:
203             {
204                 Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
205                 xProp->setPropertyValue(PROPERTY_DESCRIPTION,_rValue);
206             }
207             break;
208         case PROPERTY_ID_TYPE:
209             {
210                 Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
211                 xProp->setPropertyValue(PROPERTY_TYPE,_rValue);
212             }
213             break;
214     }
215 }
216 
getFastPropertyValue(Any & _rValue,sal_Int32 _nHandle) const217 void ODBTableDecorator::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const
218 {
219 
220     switch(_nHandle)
221     {
222         case PROPERTY_ID_PRIVILEGES:
223             {
224                 if ( -1 == m_nPrivileges )
225                     fillPrivileges();
226                 Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
227                 Reference<XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
228                 if ( xInfo->hasPropertyByName(PROPERTY_PRIVILEGES) )
229                 {
230                     _rValue <<= m_nPrivileges;
231                     break;
232                 }
233             }
234             [[fallthrough]];
235 
236         case PROPERTY_ID_FILTER:
237         case PROPERTY_ID_ORDER:
238         case PROPERTY_ID_APPLYFILTER:
239         case PROPERTY_ID_FONT:
240         case PROPERTY_ID_ROW_HEIGHT:
241         case PROPERTY_ID_AUTOGROW:
242         case PROPERTY_ID_TEXTCOLOR:
243         case PROPERTY_ID_TEXTLINECOLOR:
244         case PROPERTY_ID_TEXTEMPHASIS:
245         case PROPERTY_ID_TEXTRELIEF:
246         case PROPERTY_ID_FONTCHARWIDTH:
247         case PROPERTY_ID_FONTCHARSET:
248         case PROPERTY_ID_FONTFAMILY:
249         case PROPERTY_ID_FONTHEIGHT:
250         case PROPERTY_ID_FONTKERNING:
251         case PROPERTY_ID_FONTNAME:
252         case PROPERTY_ID_FONTORIENTATION:
253         case PROPERTY_ID_FONTPITCH:
254         case PROPERTY_ID_FONTSLANT:
255         case PROPERTY_ID_FONTSTRIKEOUT:
256         case PROPERTY_ID_FONTSTYLENAME:
257         case PROPERTY_ID_FONTUNDERLINE:
258         case PROPERTY_ID_FONTWEIGHT:
259         case PROPERTY_ID_FONTWIDTH:
260         case PROPERTY_ID_FONTWORDLINEMODE:
261         case PROPERTY_ID_FONTTYPE:
262             ODataSettings::getFastPropertyValue(_rValue, _nHandle);
263             break;
264         case PROPERTY_ID_CATALOGNAME:
265             {
266                 Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
267                 _rValue = xProp->getPropertyValue(PROPERTY_CATALOGNAME);
268             }
269             break;
270         case PROPERTY_ID_SCHEMANAME:
271             {
272                 Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
273                 _rValue = xProp->getPropertyValue(PROPERTY_SCHEMANAME);
274             }
275             break;
276         case PROPERTY_ID_NAME:
277             {
278                 Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
279                 _rValue = xProp->getPropertyValue(PROPERTY_NAME);
280             }
281             break;
282         case PROPERTY_ID_DESCRIPTION:
283             {
284                 Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
285                 _rValue = xProp->getPropertyValue(PROPERTY_DESCRIPTION);
286             }
287             break;
288         case PROPERTY_ID_TYPE:
289             {
290                 Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
291                 _rValue = xProp->getPropertyValue(PROPERTY_TYPE);
292             }
293             break;
294         default:
295             SAL_WARN("dbaccess", "Invalid Handle for table");
296     }
297 }
298 
construct()299 void ODBTableDecorator::construct()
300 {
301     bool bNotFound = true;
302     Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
303     if ( xProp.is() )
304     {
305         Reference<XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
306         bNotFound = !xInfo->hasPropertyByName(PROPERTY_PRIVILEGES);
307     }
308     if ( bNotFound )
309         registerProperty(PROPERTY_PRIVILEGES, PROPERTY_ID_PRIVILEGES, PropertyAttribute::BOUND  | PropertyAttribute::READONLY,
310                         &m_nPrivileges, ::cppu::UnoType<sal_Int32>::get());
311 }
312 
createArrayHelper(sal_Int32) const313 ::cppu::IPropertyArrayHelper* ODBTableDecorator::createArrayHelper(sal_Int32 /*_nId*/) const
314 {
315     Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
316     Reference<XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
317 
318     Sequence< Property > aTableProps = xInfo->getProperties();
319     for (Property & prop : aTableProps)
320     {
321         if (prop.Name == PROPERTY_CATALOGNAME)
322             prop.Handle = PROPERTY_ID_CATALOGNAME;
323         else if (prop.Name == PROPERTY_SCHEMANAME)
324             prop.Handle = PROPERTY_ID_SCHEMANAME;
325         else if (prop.Name == PROPERTY_NAME)
326             prop.Handle = PROPERTY_ID_NAME;
327         else if (prop.Name == PROPERTY_DESCRIPTION)
328             prop.Handle = PROPERTY_ID_DESCRIPTION;
329         else if (prop.Name == PROPERTY_TYPE)
330             prop.Handle = PROPERTY_ID_TYPE;
331         else if (prop.Name == PROPERTY_PRIVILEGES)
332             prop.Handle = PROPERTY_ID_PRIVILEGES;
333     }
334 
335     describeProperties(aTableProps);
336 
337     return new ::cppu::OPropertyArrayHelper(aTableProps);
338 }
339 
getInfoHelper()340 ::cppu::IPropertyArrayHelper & SAL_CALL ODBTableDecorator::getInfoHelper()
341 {
342     Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
343 
344     Reference<XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
345     bool bIsDescriptor = (xInfo->getPropertyByName(PROPERTY_NAME).Attributes & PropertyAttribute::READONLY) == 0;
346 
347     return *ODBTableDecorator_PROP::getArrayHelper( bIsDescriptor ? 0 : 1 );
348 
349     // TODO: this is a HACK, and prone to errors
350     // The OIdPropertyArrayUsageHelper is intended for classes where there exists a known, limited
351     // number of different property set infos (distinguished by the ID), all implemented by this very
352     // same class.
353     // However, in this case here we have an unknown, potentially unlimited number of different
354     // property set infos: Depending on the table for which we act as decorator, different property
355     // sets might exist.
356 }
357 
358 // XServiceInfo
359 IMPLEMENT_SERVICE_INFO1(ODBTableDecorator, "com.sun.star.sdb.dbaccess.ODBTableDecorator", SERVICE_SDBCX_TABLE)
360 
queryInterface(const Type & rType)361 Any SAL_CALL ODBTableDecorator::queryInterface( const Type & rType )
362 {
363     Any aRet;
364     if(m_xTable.is())
365     {
366         aRet = m_xTable->queryInterface(rType);
367         if(aRet.hasValue())
368         {   // now we know that our table supports this type so we return ourself
369             aRet = OTableDescriptor_BASE::queryInterface(rType);
370             if(!aRet.hasValue())
371                 aRet = ODataSettings::queryInterface(rType);
372         }
373     }
374 
375     return aRet;
376 }
377 
getTypes()378 Sequence< Type > SAL_CALL ODBTableDecorator::getTypes(  )
379 {
380     Reference<XTypeProvider> xTypes(m_xTable,UNO_QUERY);
381     OSL_ENSURE(xTypes.is(),"Table must be a TypeProvider!");
382     return xTypes->getTypes();
383 }
384 
385 // XRename,
rename(const OUString & _rNewName)386 void SAL_CALL ODBTableDecorator::rename( const OUString& _rNewName )
387 {
388     ::osl::MutexGuard aGuard(m_aMutex);
389     ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
390     Reference<XRename> xRename(m_xTable,UNO_QUERY);
391     if(!xRename.is())
392         throw SQLException(DBA_RES(RID_STR_NO_TABLE_RENAME),*this,SQLSTATE_GENERAL,1000,Any() );
393     // not supported
394     xRename->rename(_rNewName);
395 }
396 
397 // XAlterTable,
alterColumnByName(const OUString & _rName,const Reference<XPropertySet> & _rxDescriptor)398 void SAL_CALL ODBTableDecorator::alterColumnByName( const OUString& _rName, const Reference< XPropertySet >& _rxDescriptor )
399 {
400     ::osl::MutexGuard aGuard(m_aMutex);
401     ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
402     Reference<XAlterTable> xAlter(m_xTable,UNO_QUERY);
403     if(!xAlter.is())
404         throw SQLException(DBA_RES(RID_STR_COLUMN_ALTER_BY_NAME),*this,SQLSTATE_GENERAL,1000,Any() );
405     xAlter->alterColumnByName(_rName,_rxDescriptor);
406     if(m_pColumns)
407         m_pColumns->refresh();
408 }
409 
alterColumnByIndex(sal_Int32 _nIndex,const Reference<XPropertySet> & _rxDescriptor)410 void SAL_CALL ODBTableDecorator::alterColumnByIndex( sal_Int32 _nIndex, const Reference< XPropertySet >& _rxDescriptor )
411 {
412     ::osl::MutexGuard aGuard(m_aMutex);
413     ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
414     Reference<XAlterTable> xAlter(m_xTable,UNO_QUERY);
415     if(!xAlter.is())
416         throw SQLException(DBA_RES(RID_STR_COLUMN_ALTER_BY_INDEX),*this,SQLSTATE_GENERAL,1000,Any() );
417     // not supported
418     xAlter->alterColumnByIndex(_nIndex,_rxDescriptor);
419     if(m_pColumns)
420         m_pColumns->refresh();
421 }
422 
getIndexes()423 Reference< XNameAccess> ODBTableDecorator::getIndexes()
424 {
425     ::osl::MutexGuard aGuard(m_aMutex);
426     ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
427     return Reference< XIndexesSupplier>(m_xTable,UNO_QUERY_THROW)->getIndexes();
428 }
429 
getKeys()430 Reference< XIndexAccess> ODBTableDecorator::getKeys()
431 {
432     ::osl::MutexGuard aGuard(m_aMutex);
433     ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
434     return Reference< XKeysSupplier>(m_xTable,UNO_QUERY_THROW)->getKeys();
435 }
436 
getColumns()437 Reference< XNameAccess> ODBTableDecorator::getColumns()
438 {
439     ::osl::MutexGuard aGuard(m_aMutex);
440     ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
441 
442     if(!m_pColumns)
443         refreshColumns();
444 
445     return m_pColumns.get();
446 }
447 
getName()448 OUString SAL_CALL ODBTableDecorator::getName()
449 {
450     ::osl::MutexGuard aGuard(m_aMutex);
451     ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
452     Reference<XNamed> xName(m_xTable,UNO_QUERY);
453     OSL_ENSURE(xName.is(),"Table should support the XNamed interface");
454     return xName->getName();
455 }
456 
getSomething(const Sequence<sal_Int8> & rId)457 sal_Int64 SAL_CALL ODBTableDecorator::getSomething( const Sequence< sal_Int8 >& rId )
458 {
459     if (isUnoTunnelId<ODBTableDecorator>(rId))
460         return reinterpret_cast<sal_Int64>(this);
461 
462     sal_Int64 nRet = 0;
463     Reference<XUnoTunnel> xTunnel(m_xTable,UNO_QUERY);
464     if(xTunnel.is())
465         nRet = xTunnel->getSomething(rId);
466     return nRet;
467 }
468 
getUnoTunnelId()469 Sequence< sal_Int8 > ODBTableDecorator::getUnoTunnelId()
470 {
471     static ::cppu::OImplementationId implId;
472 
473     return implId.getImplementationId();
474 }
475 
fillPrivileges() const476 void ODBTableDecorator::fillPrivileges() const
477 {
478     // somebody is asking for the privileges and we do not know them, yet
479     m_nPrivileges = 0;
480     try
481     {
482         Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
483         if ( xProp.is() )
484         {
485             if ( xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_PRIVILEGES) )
486             {
487                 xProp->getPropertyValue(PROPERTY_PRIVILEGES) >>= m_nPrivileges;
488             }
489             if ( m_nPrivileges == 0 ) // second chance
490             {
491                 OUString sCatalog,sSchema,sName;
492                 xProp->getPropertyValue(PROPERTY_CATALOGNAME)   >>= sCatalog;
493                 xProp->getPropertyValue(PROPERTY_SCHEMANAME)    >>= sSchema;
494                 xProp->getPropertyValue(PROPERTY_NAME)          >>= sName;
495                 m_nPrivileges = ::dbtools::getTablePrivileges(m_xMetaData, sCatalog,sSchema, sName);
496             }
497         }
498     }
499     catch(const SQLException&)
500     {
501         SAL_WARN("dbaccess", "ODBTableDecorator::ODBTableDecorator : could not collect the privileges !");
502     }
503 }
504 
createDataDescriptor()505 Reference< XPropertySet > SAL_CALL ODBTableDecorator::createDataDescriptor(  )
506 {
507     ::osl::MutexGuard aGuard(m_aMutex);
508     ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
509 
510     Reference< XDataDescriptorFactory > xFactory( m_xTable, UNO_QUERY );
511     OSL_ENSURE( xFactory.is(), "ODBTableDecorator::createDataDescriptor: invalid table!" );
512     Reference< XColumnsSupplier > xColsSupp;
513     if ( xFactory.is() )
514         xColsSupp.set(xFactory->createDataDescriptor(), css::uno::UNO_QUERY);
515 
516     return new ODBTableDecorator(
517         m_xConnection,
518         xColsSupp,
519         m_xNumberFormats,
520         nullptr
521     );
522 }
523 
getPropertySetInfo()524 Reference< css::beans::XPropertySetInfo > SAL_CALL ODBTableDecorator::getPropertySetInfo(  )
525 {
526     return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
527 }
528 
refreshColumns()529 void ODBTableDecorator::refreshColumns()
530 {
531     ::osl::MutexGuard aGuard(m_aMutex);
532     ::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
533 
534     std::vector< OUString> aVector;
535 
536     Reference<XNameAccess> xNames;
537     if(m_xTable.is())
538     {
539         xNames = m_xTable->getColumns();
540         if(xNames.is())
541         {
542             Sequence< OUString> aNames = xNames->getElementNames();
543             const OUString* pIter    = aNames.getConstArray();
544             const OUString* pEnd     = pIter + aNames.getLength();
545             for(;pIter != pEnd;++pIter)
546                 aVector.push_back(*pIter);
547         }
548     }
549     if(!m_pColumns)
550     {
551         OColumns* pCol = new OColumns(*this,m_aMutex,xNames,m_xMetaData.is() && m_xMetaData->supportsMixedCaseQuotedIdentifiers(),aVector,
552                                     this,this,
553                                     m_xMetaData.is() && m_xMetaData->supportsAlterTableWithAddColumn(),
554                                     m_xMetaData.is() && m_xMetaData->supportsAlterTableWithDropColumn());
555 
556         pCol->setParent(*this);
557         OContainerMediator* pMediator = new OContainerMediator( pCol, m_xColumnDefinitions );
558         m_xColumnMediator = pMediator;
559         pCol->setMediator( pMediator );
560         m_pColumns.reset(pCol);
561     }
562     else
563         m_pColumns->reFill(aVector);
564 }
565 
createColumn(const OUString & _rName) const566 OColumn* ODBTableDecorator::createColumn(const OUString& _rName) const
567 {
568     OColumn* pReturn = nullptr;
569 
570     Reference<XNameAccess> xNames;
571     if ( m_xTable.is() )
572     {
573         xNames = m_xTable->getColumns();
574 
575         if ( xNames.is() && xNames->hasByName(_rName) )
576         {
577             Reference<XPropertySet> xProp(xNames->getByName(_rName),UNO_QUERY);
578 
579             Reference<XPropertySet> xColumnDefintion;
580             if ( m_xColumnDefinitions.is() && m_xColumnDefinitions->hasByName(_rName))
581                 xColumnDefintion.set(m_xColumnDefinitions->getByName(_rName),UNO_QUERY);
582 
583             pReturn = new OTableColumnWrapper( xProp, xColumnDefintion, false );
584         }
585     }
586     return pReturn;
587 }
588 
columnAppended(const Reference<XPropertySet> &)589 void ODBTableDecorator::columnAppended( const Reference< XPropertySet >& /*_rxSourceDescriptor*/ )
590 {
591     // not interested in
592 }
593 
columnDropped(const OUString & _sName)594 void ODBTableDecorator::columnDropped(const OUString& _sName)
595 {
596     Reference<XDrop> xDrop(m_xColumnDefinitions,UNO_QUERY);
597     if ( xDrop.is() && m_xColumnDefinitions->hasByName(_sName) )
598         xDrop->dropByName(_sName);
599 }
600 
createColumnDescriptor()601 Reference< XPropertySet > ODBTableDecorator::createColumnDescriptor()
602 {
603     Reference<XDataDescriptorFactory> xNames;
604     if(m_xTable.is())
605         xNames.set(m_xTable->getColumns(),UNO_QUERY);
606     Reference< XPropertySet > xRet;
607     if ( xNames.is() )
608         xRet = new OTableColumnDescriptorWrapper( xNames->createDataDescriptor(), false, true );
609     return xRet;
610 }
611 
acquire()612 void SAL_CALL ODBTableDecorator::acquire() throw()
613 {
614     OTableDescriptor_BASE::acquire();
615 }
616 
release()617 void SAL_CALL ODBTableDecorator::release() throw()
618 {
619     OTableDescriptor_BASE::release();
620 }
621 
setName(const OUString &)622 void SAL_CALL ODBTableDecorator::setName( const OUString& /*aName*/ )
623 {
624     throwFunctionNotSupportedRuntimeException( "XNamed::setName", *this );
625 }
626 
627 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
628