1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbaccess.hxx"
26 
27 #ifndef _DBA_CORE_TABLEDECORATOR_HXX_
28 #include "TableDeco.hxx"
29 #endif
30 #ifndef _DBACORE_DEFINITIONCOLUMN_HXX_
31 #include <definitioncolumn.hxx>
32 #endif
33 #ifndef DBACCESS_SHARED_DBASTRINGS_HRC
34 #include "dbastrings.hrc"
35 #endif
36 #ifndef _DBA_CORE_RESOURCE_HXX_
37 #include "core_resource.hxx"
38 #endif
39 #ifndef _DBA_CORE_RESOURCE_HRC_
40 #include "core_resource.hrc"
41 #endif
42 #ifndef _TOOLS_DEBUG_HXX
43 #include <tools/debug.hxx>
44 #endif
45 
46 #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
47 #include <cppuhelper/typeprovider.hxx>
48 #endif
49 #ifndef _COMPHELPER_ENUMHELPER_HXX_
50 #include <comphelper/enumhelper.hxx>
51 #endif
52 #ifndef _COMPHELPER_CONTAINER_HXX_
53 #include <comphelper/container.hxx>
54 #endif
55 #ifndef _COMPHELPER_SEQUENCE_HXX_
56 #include <comphelper/sequence.hxx>
57 #endif
58 #ifndef _COMPHELPER_PROPERTY_HXX_
59 #include <comphelper/property.hxx>
60 #endif
61 #ifndef _COMPHELPER_TYPES_HXX_
62 #include <comphelper/types.hxx>
63 #endif
64 #ifndef _COM_SUN_STAR_UTIL_XREFRESHLISTENER_HPP_
65 #include <com/sun/star/util/XRefreshListener.hpp>
66 #endif
67 #ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
68 #include <com/sun/star/sdbc/XConnection.hpp>
69 #endif
70 #ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
71 #include <com/sun/star/sdbc/XRow.hpp>
72 #endif
73 #ifndef _COM_SUN_STAR_SDBCX_PRIVILEGE_HPP_
74 #include <com/sun/star/sdbcx/Privilege.hpp>
75 #endif
76 #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
77 #include <com/sun/star/beans/PropertyAttribute.hpp>
78 #endif
79 #ifndef _CONNECTIVITY_DBTOOLS_HXX_
80 #include <connectivity/dbtools.hxx>
81 #endif
82 #ifndef _DBHELPER_DBEXCEPTION_HXX_
83 #include <connectivity/dbexception.hxx>
84 #endif
85 #ifndef _CONNECTIVITY_DBTOOLS_HXX_
86 #include <connectivity/dbtools.hxx>
87 #endif
88 #ifndef _COMPHELPER_EXTRACT_HXX_
89 #include <comphelper/extract.hxx>
90 #endif
91 #ifndef DBA_CONTAINERMEDIATOR_HXX
92 #include "ContainerMediator.hxx"
93 #endif
94 #include <rtl/logfile.hxx>
95 
96 using namespace dbaccess;
97 using namespace ::com::sun::star::uno;
98 using namespace ::com::sun::star::util;
99 using namespace ::com::sun::star::lang;
100 using namespace ::com::sun::star::beans;
101 using namespace ::com::sun::star::sdbc;
102 using namespace ::com::sun::star::sdbcx;
103 using namespace ::com::sun::star::container;
104 using namespace ::osl;
105 using namespace ::comphelper;
106 using namespace ::dbtools;
107 using namespace ::cppu;
108 
109 //==========================================================================
110 //= ODBTableDecorator
111 //==========================================================================
112 DBG_NAME(ODBTableDecorator)
113 // -----------------------------------------------------------------------------
114 ODBTableDecorator::ODBTableDecorator( const Reference< XConnection >& _rxConnection, const Reference< XColumnsSupplier >& _rxNewTable,
115 		const Reference< XNumberFormatsSupplier >& _rxNumberFormats, const Reference< XNameAccess >& _xColumnDefinitions ) throw(SQLException)
116 	:OTableDescriptor_BASE(m_aMutex)
117 	,ODataSettings(OTableDescriptor_BASE::rBHelper)
118 	,m_xTable(_rxNewTable)
119 	,m_xColumnDefinitions(_xColumnDefinitions)
120     ,m_xConnection( _rxConnection )
121     ,m_xMetaData( _rxConnection.is() ? _rxConnection->getMetaData() : Reference< XDatabaseMetaData >() )
122 	,m_xNumberFormats( _rxNumberFormats )
123 	,m_nPrivileges(-1)
124 	,m_pColumns(NULL)
125 {
126     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::ODBTableDecorator" );
127 	DBG_CTOR(ODBTableDecorator, NULL);
128 	ODataSettings::registerPropertiesFor(this);
129 }
130 // -------------------------------------------------------------------------
131 ODBTableDecorator::~ODBTableDecorator()
132 {
133 	DBG_DTOR(ODBTableDecorator, NULL);
134 	if ( m_pColumns )
135 		delete m_pColumns;
136 }
137 
138 //--------------------------------------------------------------------------
139 Sequence< sal_Int8 > ODBTableDecorator::getImplementationId() throw (RuntimeException)
140 {
141     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getImplementationId" );
142 	static OImplementationId * pId = 0;
143 	if (! pId)
144 	{
145 		MutexGuard aGuard( Mutex::getGlobalMutex() );
146 		if (! pId)
147 		{
148 			static OImplementationId aId;
149 			pId = &aId;
150 		}
151 	}
152 	return pId->getImplementationId();
153 }
154 
155 // OComponentHelper
156 //------------------------------------------------------------------------------
157 void SAL_CALL ODBTableDecorator::disposing()
158 {
159     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::disposing" );
160 	OPropertySetHelper::disposing();
161 	OTableDescriptor_BASE::disposing();
162 
163 	MutexGuard aGuard(m_aMutex);
164 	m_xTable		= NULL;
165 	m_xMetaData		= NULL;
166 	m_pTables		= NULL;
167 	m_xColumnDefinitions = NULL;
168 	m_xNumberFormats = NULL;
169 	if ( m_pColumns )
170 		m_pColumns->disposing();
171     m_xColumnMediator = NULL;
172 }
173 // -----------------------------------------------------------------------------
174 sal_Bool SAL_CALL ODBTableDecorator::convertFastPropertyValue(
175 							Any & rConvertedValue,
176 							Any & rOldValue,
177 							sal_Int32 nHandle,
178 							const Any& rValue )
179 								throw (::com::sun::star::lang::IllegalArgumentException)
180 {
181     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::convertFastPropertyValue" );
182 	sal_Bool bRet = sal_True;
183 	switch(nHandle)
184 	{
185 		case PROPERTY_ID_PRIVILEGES:
186 		case PROPERTY_ID_FILTER:
187 		case PROPERTY_ID_ORDER:
188 		case PROPERTY_ID_APPLYFILTER:
189 		case PROPERTY_ID_FONT:
190 		case PROPERTY_ID_ROW_HEIGHT:
191 		case PROPERTY_ID_TEXTCOLOR:
192 		case PROPERTY_ID_TEXTLINECOLOR:
193 		case PROPERTY_ID_TEXTEMPHASIS:
194 		case PROPERTY_ID_TEXTRELIEF:
195 		case PROPERTY_ID_FONTCHARWIDTH:
196 		case PROPERTY_ID_FONTCHARSET:
197 		case PROPERTY_ID_FONTFAMILY:
198 		case PROPERTY_ID_FONTHEIGHT:
199 		case PROPERTY_ID_FONTKERNING:
200 		case PROPERTY_ID_FONTNAME:
201 		case PROPERTY_ID_FONTORIENTATION:
202 		case PROPERTY_ID_FONTPITCH:
203 		case PROPERTY_ID_FONTSLANT:
204 		case PROPERTY_ID_FONTSTRIKEOUT:
205 		case PROPERTY_ID_FONTSTYLENAME:
206 		case PROPERTY_ID_FONTUNDERLINE:
207 		case PROPERTY_ID_FONTWEIGHT:
208 		case PROPERTY_ID_FONTWIDTH:
209 		case PROPERTY_ID_FONTWORDLINEMODE:
210 		case PROPERTY_ID_FONTTYPE:
211 			bRet = ODataSettings::convertFastPropertyValue(rConvertedValue, rOldValue,nHandle,rValue);
212 			break;
213 
214 		default:
215 			{
216 				Any aValue;
217 				getFastPropertyValue(aValue,nHandle);
218 				bRet = ::comphelper::tryPropertyValue(rConvertedValue,rOldValue,rValue,aValue,::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
219 			}
220 			break; // we assume that it works
221 	}
222 	return bRet;
223 }
224 // -----------------------------------------------------------------------------
225 void ODBTableDecorator::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) throw (Exception)
226 {
227     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::setFastPropertyValue_NoBroadcast" );
228 	switch(_nHandle)
229 	{
230 		case PROPERTY_ID_PRIVILEGES:
231 			OSL_ENSURE(0,"Property is readonly!");
232 		case PROPERTY_ID_FILTER:
233 		case PROPERTY_ID_ORDER:
234 		case PROPERTY_ID_APPLYFILTER:
235 		case PROPERTY_ID_FONT:
236 		case PROPERTY_ID_ROW_HEIGHT:
237 		case PROPERTY_ID_TEXTCOLOR:
238 		case PROPERTY_ID_TEXTLINECOLOR:
239 		case PROPERTY_ID_TEXTEMPHASIS:
240 		case PROPERTY_ID_TEXTRELIEF:
241 		case PROPERTY_ID_FONTCHARWIDTH:
242 		case PROPERTY_ID_FONTCHARSET:
243 		case PROPERTY_ID_FONTFAMILY:
244 		case PROPERTY_ID_FONTHEIGHT:
245 		case PROPERTY_ID_FONTKERNING:
246 		case PROPERTY_ID_FONTNAME:
247 		case PROPERTY_ID_FONTORIENTATION:
248 		case PROPERTY_ID_FONTPITCH:
249 		case PROPERTY_ID_FONTSLANT:
250 		case PROPERTY_ID_FONTSTRIKEOUT:
251 		case PROPERTY_ID_FONTSTYLENAME:
252 		case PROPERTY_ID_FONTUNDERLINE:
253 		case PROPERTY_ID_FONTWEIGHT:
254 		case PROPERTY_ID_FONTWIDTH:
255 		case PROPERTY_ID_FONTWORDLINEMODE:
256 		case PROPERTY_ID_FONTTYPE:
257 
258 			ODataSettings::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
259 			break;
260 		case PROPERTY_ID_CATALOGNAME:
261 			{
262 				Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
263 				xProp->setPropertyValue(PROPERTY_CATALOGNAME,_rValue);
264 			}
265 			break;
266 		case PROPERTY_ID_SCHEMANAME:
267 			{
268 				Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
269 				xProp->setPropertyValue(PROPERTY_SCHEMANAME,_rValue);
270 			}
271 			break;
272 		case PROPERTY_ID_NAME:
273 			{
274 				Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
275 				xProp->setPropertyValue(PROPERTY_NAME,_rValue);
276 			}
277 			break;
278 		case PROPERTY_ID_DESCRIPTION:
279 			{
280 				Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
281 				xProp->setPropertyValue(PROPERTY_DESCRIPTION,_rValue);
282 			}
283 			break;
284 		case PROPERTY_ID_TYPE:
285 			{
286 				Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
287 				xProp->setPropertyValue(PROPERTY_TYPE,_rValue);
288 			}
289 			break;
290 	}
291 }
292 //------------------------------------------------------------------------------
293 void ODBTableDecorator::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const
294 {
295     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getFastPropertyValue" );
296 	switch(_nHandle)
297 	{
298 		case PROPERTY_ID_PRIVILEGES:
299 			{
300 				if ( -1 == m_nPrivileges )
301 					fillPrivileges();
302 				Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
303 				Reference<XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
304 				if ( xInfo->hasPropertyByName(PROPERTY_PRIVILEGES) )
305 				{
306 					_rValue <<= m_nPrivileges;
307 					break;
308 				}
309 			}
310 			// run through
311 
312 		case PROPERTY_ID_FILTER:
313 		case PROPERTY_ID_ORDER:
314 		case PROPERTY_ID_APPLYFILTER:
315 		case PROPERTY_ID_FONT:
316 		case PROPERTY_ID_ROW_HEIGHT:
317 		case PROPERTY_ID_TEXTCOLOR:
318 		case PROPERTY_ID_TEXTLINECOLOR:
319 		case PROPERTY_ID_TEXTEMPHASIS:
320 		case PROPERTY_ID_TEXTRELIEF:
321 		case PROPERTY_ID_FONTCHARWIDTH:
322 		case PROPERTY_ID_FONTCHARSET:
323 		case PROPERTY_ID_FONTFAMILY:
324 		case PROPERTY_ID_FONTHEIGHT:
325 		case PROPERTY_ID_FONTKERNING:
326 		case PROPERTY_ID_FONTNAME:
327 		case PROPERTY_ID_FONTORIENTATION:
328 		case PROPERTY_ID_FONTPITCH:
329 		case PROPERTY_ID_FONTSLANT:
330 		case PROPERTY_ID_FONTSTRIKEOUT:
331 		case PROPERTY_ID_FONTSTYLENAME:
332 		case PROPERTY_ID_FONTUNDERLINE:
333 		case PROPERTY_ID_FONTWEIGHT:
334 		case PROPERTY_ID_FONTWIDTH:
335 		case PROPERTY_ID_FONTWORDLINEMODE:
336 		case PROPERTY_ID_FONTTYPE:
337 			ODataSettings::getFastPropertyValue(_rValue, _nHandle);
338 			break;
339 		case PROPERTY_ID_CATALOGNAME:
340 			{
341 				Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
342 				_rValue = xProp->getPropertyValue(PROPERTY_CATALOGNAME);
343 			}
344 			break;
345 		case PROPERTY_ID_SCHEMANAME:
346 			{
347 				Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
348 				_rValue = xProp->getPropertyValue(PROPERTY_SCHEMANAME);
349 			}
350 			break;
351 		case PROPERTY_ID_NAME:
352 			{
353 				Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
354 				_rValue = xProp->getPropertyValue(PROPERTY_NAME);
355 			}
356 			break;
357 		case PROPERTY_ID_DESCRIPTION:
358 			{
359 				Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
360 				_rValue = xProp->getPropertyValue(PROPERTY_DESCRIPTION);
361 			}
362 			break;
363 		case PROPERTY_ID_TYPE:
364 			{
365 				Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
366 				_rValue = xProp->getPropertyValue(PROPERTY_TYPE);
367 			}
368 			break;
369 		default:
370 			OSL_ENSURE(0,"Invalid Handle for table");
371 	}
372 }
373 // -------------------------------------------------------------------------
374 void ODBTableDecorator::construct()
375 {
376     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::construct" );
377 	sal_Bool bNotFound = sal_True;
378 	Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
379 	if ( xProp.is() )
380 	{
381 		Reference<XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
382 		bNotFound = !xInfo->hasPropertyByName(PROPERTY_PRIVILEGES);
383 	}
384 	if ( bNotFound )
385 		registerProperty(PROPERTY_PRIVILEGES, PROPERTY_ID_PRIVILEGES, PropertyAttribute::BOUND  | PropertyAttribute::READONLY,
386 						&m_nPrivileges, ::getCppuType(static_cast<sal_Int32*>(NULL)));
387 }
388 // -----------------------------------------------------------------------------
389 ::cppu::IPropertyArrayHelper* ODBTableDecorator::createArrayHelper(sal_Int32 /*_nId*/) const
390 {
391     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::createArrayHelper" );
392 	Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
393 	Reference<XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
394 
395 	Sequence< Property > aTableProps = xInfo->getProperties();
396 	Property* pIter = aTableProps.getArray();
397 	Property* pEnd = pIter + aTableProps.getLength();
398 	for (;pIter != pEnd ; ++pIter)
399 	{
400 		if (0 == pIter->Name.compareToAscii(PROPERTY_CATALOGNAME))
401 			pIter->Handle = PROPERTY_ID_CATALOGNAME;
402 		else if (0 ==pIter->Name.compareToAscii(PROPERTY_SCHEMANAME))
403 			pIter->Handle = PROPERTY_ID_SCHEMANAME;
404 		else if (0 ==pIter->Name.compareToAscii(PROPERTY_NAME))
405 			pIter->Handle = PROPERTY_ID_NAME;
406 		else if (0 ==pIter->Name.compareToAscii(PROPERTY_DESCRIPTION))
407 			pIter->Handle = PROPERTY_ID_DESCRIPTION;
408 		else if (0 ==pIter->Name.compareToAscii(PROPERTY_TYPE))
409 			pIter->Handle = PROPERTY_ID_TYPE;
410 		else if (0 ==pIter->Name.compareToAscii(PROPERTY_PRIVILEGES))
411 			pIter->Handle = PROPERTY_ID_PRIVILEGES;
412 	}
413 
414 	describeProperties(aTableProps);
415 
416 	return new ::cppu::OPropertyArrayHelper(aTableProps);
417 }
418 // -----------------------------------------------------------------------------
419 ::cppu::IPropertyArrayHelper & SAL_CALL ODBTableDecorator::getInfoHelper()
420 {
421     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getInfoHelper" );
422 	Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
423 
424 	Reference<XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
425     bool bIsDescriptor = (xInfo->getPropertyByName(PROPERTY_NAME).Attributes & PropertyAttribute::READONLY) == 0;
426 
427     return *ODBTableDecorator_PROP::getArrayHelper( bIsDescriptor ? 0 : 1 );
428 
429     // TODO: this is a HACK, and prone to errors
430     // The OIdPropertyArrayUsageHelper is intended for classes where there exists a known, limited
431     // number of different property set infos (distinguished by the ID), all implemented by this very
432     // same class.
433     // However, in this case here we have an unknown, potentially unlimited number of different
434     // property set infos: Depending on the table for which we act as decorator, different property
435     // sets might exist.
436 }
437 // -------------------------------------------------------------------------
438 // XServiceInfo
439 IMPLEMENT_SERVICE_INFO1(ODBTableDecorator, "com.sun.star.sdb.dbaccess.ODBTableDecorator", SERVICE_SDBCX_TABLE)
440 // -------------------------------------------------------------------------
441 Any SAL_CALL ODBTableDecorator::queryInterface( const Type & rType ) throw(RuntimeException)
442 {
443     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::queryInterface" );
444 	Any aRet;
445 	if(m_xTable.is())
446 	{
447 		aRet = m_xTable->queryInterface(rType);
448 		if(aRet.hasValue())
449 		{	// now we know that our table supports this type so we return ourself
450 			aRet = OTableDescriptor_BASE::queryInterface(rType);
451 			if(!aRet.hasValue())
452 				aRet = ODataSettings::queryInterface(rType);
453 		}
454 	}
455 
456 	return aRet;
457 }
458 // -------------------------------------------------------------------------
459 Sequence< Type > SAL_CALL ODBTableDecorator::getTypes(  ) throw(RuntimeException)
460 {
461     //RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getTypes" );
462 	Reference<XTypeProvider> xTypes(m_xTable,UNO_QUERY);
463 	OSL_ENSURE(xTypes.is(),"Table must be a TypePropvider!");
464 	return xTypes->getTypes();
465 }
466 
467 // -----------------------------------------------------------------------------
468 // XRename,
469 //------------------------------------------------------------------------------
470 void SAL_CALL ODBTableDecorator::rename( const ::rtl::OUString& _rNewName ) throw(SQLException, ElementExistException, RuntimeException)
471 {
472     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::rename" );
473 	::osl::MutexGuard aGuard(m_aMutex);
474 	::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
475 	Reference<XRename> xRename(m_xTable,UNO_QUERY);
476 	if(xRename.is())
477 	{
478 //		::rtl::OUString sOldName;
479 //		Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
480 //		xProp->getPropertyValue(PROPERTY_NAME) >>= sOldName;
481 		xRename->rename(_rNewName);
482 	}
483 	else // not supported
484 		throw SQLException(DBACORE_RESSTRING(RID_STR_NO_TABLE_RENAME),*this,SQLSTATE_GENERAL,1000,Any() );
485 }
486 
487 // XAlterTable,
488 //------------------------------------------------------------------------------
489 void SAL_CALL ODBTableDecorator::alterColumnByName( const ::rtl::OUString& _rName, const Reference< XPropertySet >& _rxDescriptor ) throw(SQLException, NoSuchElementException, RuntimeException)
490 {
491     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::alterColumnByName" );
492 	::osl::MutexGuard aGuard(m_aMutex);
493 	::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
494 	Reference<XAlterTable> xAlter(m_xTable,UNO_QUERY);
495 	if(xAlter.is())
496 	{
497 		xAlter->alterColumnByName(_rName,_rxDescriptor);
498 	}
499 	else
500 		throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_ALTER_BY_NAME),*this,SQLSTATE_GENERAL,1000,Any() );
501 	if(m_pColumns)
502 		m_pColumns->refresh();
503 }
504 
505 //------------------------------------------------------------------------------
506 void SAL_CALL ODBTableDecorator::alterColumnByIndex( sal_Int32 _nIndex, const Reference< XPropertySet >& _rxDescriptor ) throw(SQLException, IndexOutOfBoundsException, RuntimeException)
507 {
508     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::alterColumnByIndex" );
509 	::osl::MutexGuard aGuard(m_aMutex);
510 	::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
511 	Reference<XAlterTable> xAlter(m_xTable,UNO_QUERY);
512 	if(xAlter.is())
513 	{
514 		xAlter->alterColumnByIndex(_nIndex,_rxDescriptor);
515 		if(m_pColumns)
516 			m_pColumns->refresh();
517 	}
518 	else // not supported
519 		throw SQLException(DBACORE_RESSTRING(RID_STR_COLUMN_ALTER_BY_INDEX),*this,SQLSTATE_GENERAL,1000,Any() );
520 }
521 // -----------------------------------------------------------------------------
522 Reference< XNameAccess> ODBTableDecorator::getIndexes() throw (RuntimeException)
523 {
524     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getIndexes" );
525 	::osl::MutexGuard aGuard(m_aMutex);
526 	::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
527 	return Reference< XIndexesSupplier>(m_xTable,UNO_QUERY)->getIndexes();
528 }
529 // -------------------------------------------------------------------------
530 Reference< XIndexAccess> ODBTableDecorator::getKeys() throw (RuntimeException)
531 {
532     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getKeys" );
533 	::osl::MutexGuard aGuard(m_aMutex);
534 	::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
535 	return Reference< XKeysSupplier>(m_xTable,UNO_QUERY)->getKeys();
536 }
537 // -------------------------------------------------------------------------
538 Reference< XNameAccess> ODBTableDecorator::getColumns() throw (RuntimeException)
539 {
540     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getColumns" );
541 	::osl::MutexGuard aGuard(m_aMutex);
542 	::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
543 
544 	if(!m_pColumns)
545 		refreshColumns();
546 
547 	return m_pColumns;
548 }
549 // -----------------------------------------------------------------------------
550 ::rtl::OUString SAL_CALL ODBTableDecorator::getName() throw(RuntimeException)
551 {
552     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getName" );
553 	::osl::MutexGuard aGuard(m_aMutex);
554 	::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
555 	Reference<XNamed> xName(m_xTable,UNO_QUERY);
556 	OSL_ENSURE(xName.is(),"Table should support the XNamed interface");
557 	return xName->getName();
558 }
559 // -----------------------------------------------------------------------------
560 sal_Int64 SAL_CALL ODBTableDecorator::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException)
561 {
562     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getSomething" );
563 	if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
564 		return reinterpret_cast<sal_Int64>(this);
565 
566 	sal_Int64 nRet = 0;
567 	Reference<XUnoTunnel> xTunnel(m_xTable,UNO_QUERY);
568 	if(xTunnel.is())
569 		nRet = xTunnel->getSomething(rId);
570 	return nRet;
571 }
572 // -----------------------------------------------------------------------------
573 Sequence< sal_Int8 > ODBTableDecorator::getUnoTunnelImplementationId()
574 {
575     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getUnoTunnelImplementationId" );
576 	static ::cppu::OImplementationId * pId = 0;
577 	if (! pId)
578 	{
579 		::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
580 		if (! pId)
581 		{
582 			static ::cppu::OImplementationId aId;
583 			pId = &aId;
584 		}
585 	}
586 	return pId->getImplementationId();
587 }
588 // -----------------------------------------------------------------------------
589 void ODBTableDecorator::fillPrivileges() const
590 {
591     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::fillPrivileges" );
592 	// somebody is asking for the privileges an we do not know them, yet
593 	m_nPrivileges = 0;
594 	try
595 	{
596 		Reference<XPropertySet> xProp(m_xTable,UNO_QUERY);
597 		if ( xProp.is() )
598 		{
599 			if ( xProp->getPropertySetInfo()->hasPropertyByName(PROPERTY_PRIVILEGES) )
600 			{
601 				xProp->getPropertyValue(PROPERTY_PRIVILEGES) >>= m_nPrivileges;
602 			}
603 			if ( m_nPrivileges == 0 ) // second chance
604 			{
605 				::rtl::OUString sCatalog,sSchema,sName;
606 				xProp->getPropertyValue(PROPERTY_CATALOGNAME)	>>= sCatalog;
607 				xProp->getPropertyValue(PROPERTY_SCHEMANAME)	>>= sSchema;
608 				xProp->getPropertyValue(PROPERTY_NAME)			>>= sName;
609 				m_nPrivileges = ::dbtools::getTablePrivileges(getMetaData(),sCatalog,sSchema, sName);
610 			}
611 		}
612 	}
613 	catch(const SQLException& e)
614 	{
615         (void)e;
616 		DBG_ERROR("ODBTableDecorator::ODBTableDecorator : could not collect the privileges !");
617 	}
618 }
619 // -----------------------------------------------------------------------------
620 Reference< XPropertySet > SAL_CALL ODBTableDecorator::createDataDescriptor(  ) throw (RuntimeException)
621 {
622     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::createDataDescriptor" );
623 	::osl::MutexGuard aGuard(m_aMutex);
624 	::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
625 
626 	Reference< XDataDescriptorFactory > xFactory( m_xTable, UNO_QUERY );
627 	DBG_ASSERT( xFactory.is(), "ODBTableDecorator::createDataDescriptor: invalid table!" );
628 	Reference< XColumnsSupplier > xColsSupp;
629 	if ( xFactory.is() )
630 		xColsSupp = xColsSupp.query( xFactory->createDataDescriptor() );
631 
632 	return new ODBTableDecorator(
633 		m_xConnection,
634 		xColsSupp,
635 		m_xNumberFormats,
636 		NULL
637 	);
638 }
639 // -----------------------------------------------------------------------------
640 Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL ODBTableDecorator::getPropertySetInfo(  ) throw(RuntimeException)
641 {
642     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::getPropertySetInfo" );
643 	return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
644 }
645 // -----------------------------------------------------------------------------
646 void ODBTableDecorator::refreshColumns()
647 {
648     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::refreshColumns" );
649 	::osl::MutexGuard aGuard(m_aMutex);
650 	::connectivity::checkDisposed(OTableDescriptor_BASE::rBHelper.bDisposed);
651 
652 	::std::vector< ::rtl::OUString> aVector;
653 
654 	Reference<XNameAccess> xNames;
655 	if(m_xTable.is())
656 	{
657 		xNames = m_xTable->getColumns();
658 		if(xNames.is())
659 		{
660 			Sequence< ::rtl::OUString> aNames = xNames->getElementNames();
661 			const ::rtl::OUString* pIter	= aNames.getConstArray();
662 			const ::rtl::OUString* pEnd		= pIter + aNames.getLength();
663 			for(;pIter != pEnd;++pIter)
664 				aVector.push_back(*pIter);
665 		}
666 	}
667 	if(!m_pColumns)
668 	{
669 		OColumns* pCol = new OColumns(*this,m_aMutex,xNames,m_xMetaData.is() && m_xMetaData->supportsMixedCaseQuotedIdentifiers(),aVector,
670 									this,this,
671 									m_xMetaData.is() && m_xMetaData->supportsAlterTableWithAddColumn(),
672 									m_xMetaData.is() && m_xMetaData->supportsAlterTableWithDropColumn());
673 
674 		pCol->setParent(*this);
675         OContainerMediator* pMediator = new OContainerMediator( pCol, m_xColumnDefinitions, m_xConnection, OContainerMediator::eColumns );
676 		m_xColumnMediator = pMediator;
677 		pCol->setMediator( pMediator );
678 		m_pColumns	= pCol;
679 	}
680 	else
681 		m_pColumns->reFill(aVector);
682 }
683 // -----------------------------------------------------------------------------
684 OColumn* ODBTableDecorator::createColumn(const ::rtl::OUString& _rName) const
685 {
686     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::createColumn" );
687 	OColumn* pReturn = NULL;
688 
689 	Reference<XNameAccess> xNames;
690 	if ( m_xTable.is() )
691 	{
692 		xNames = m_xTable->getColumns();
693 
694 		if ( xNames.is() && xNames->hasByName(_rName) )
695 		{
696 			Reference<XPropertySet> xProp(xNames->getByName(_rName),UNO_QUERY);
697 
698 			Reference<XPropertySet> xColumnDefintion;
699 			if ( m_xColumnDefinitions.is() && m_xColumnDefinitions->hasByName(_rName))
700 				xColumnDefintion.set(m_xColumnDefinitions->getByName(_rName),UNO_QUERY);
701 
702 			pReturn = new OTableColumnWrapper( xProp, xColumnDefintion, false );
703 		}
704 	}
705 	return pReturn;
706 }
707 // -----------------------------------------------------------------------------
708 void ODBTableDecorator::columnAppended( const Reference< XPropertySet >& /*_rxSourceDescriptor*/ )
709 {
710     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::columnAppended" );
711     // not interested in
712 }
713 // -----------------------------------------------------------------------------
714 void ODBTableDecorator::columnDropped(const ::rtl::OUString& _sName)
715 {
716     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::columnDropped" );
717 	Reference<XDrop> xDrop(m_xColumnDefinitions,UNO_QUERY);
718 	if ( xDrop.is() && m_xColumnDefinitions->hasByName(_sName) )
719 		xDrop->dropByName(_sName);
720 }
721 
722 // -----------------------------------------------------------------------------
723 Reference< XPropertySet > ODBTableDecorator::createColumnDescriptor()
724 {
725     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::createColumnDescriptor" );
726 	Reference<XDataDescriptorFactory> xNames;
727 	if(m_xTable.is())
728 		xNames.set(m_xTable->getColumns(),UNO_QUERY);
729 	Reference< XPropertySet > xRet;
730 	if ( xNames.is() )
731 		xRet = new OTableColumnDescriptorWrapper( xNames->createDataDescriptor(), false, true );
732 	return xRet;
733 }
734 // -----------------------------------------------------------------------------
735 void SAL_CALL ODBTableDecorator::acquire() throw()
736 {
737 	OTableDescriptor_BASE::acquire();
738 }
739 // -----------------------------------------------------------------------------
740 void SAL_CALL ODBTableDecorator::release() throw()
741 {
742 	OTableDescriptor_BASE::release();
743 }
744 
745 // -----------------------------------------------------------------------------
746 void SAL_CALL ODBTableDecorator::setName( const ::rtl::OUString& /*aName*/ ) throw (::com::sun::star::uno::RuntimeException)
747 {
748     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "Ocke.Janssen@sun.com", "ODBTableDecorator::setName" );
749     throwFunctionNotSupportedException( "XNamed::setName", *this );
750 }
751 
752 // -----------------------------------------------------------------------------
753 
754 
755