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