Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / dbaccess / source / core / api / column.cxx
blobd5a867747ca5f3ef6768e2977627a5e27fc0f620
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "ContainerMediator.hxx"
22 #include "apitools.hxx"
23 #include "column.hxx"
24 #include "core_resource.hrc"
25 #include "core_resource.hxx"
26 #include "dbastrings.hrc"
27 #include "sdbcoretools.hxx"
29 #include <com/sun/star/lang/DisposedException.hpp>
30 #include <com/sun/star/sdbc/ColumnValue.hpp>
31 #include <com/sun/star/sdbc/DataType.hpp>
33 #include <comphelper/basicio.hxx>
34 #include <comphelper/enumhelper.hxx>
35 #include <comphelper/extract.hxx>
36 #include <comphelper/property.hxx>
37 #include <comphelper/seqstream.hxx>
38 #include <comphelper/sequence.hxx>
39 #include <comphelper/types.hxx>
40 #include <connectivity/TTableHelper.hxx>
41 #include <connectivity/dbexception.hxx>
42 #include <connectivity/dbtools.hxx>
43 #include <cppuhelper/typeprovider.hxx>
44 #include <osl/diagnose.h>
45 #include <tools/debug.hxx>
47 #include <algorithm>
49 using namespace dbaccess;
50 using namespace connectivity;
51 using namespace connectivity;
52 using namespace ::com::sun::star::sdbc;
53 using namespace ::com::sun::star::sdbcx;
54 using namespace ::com::sun::star::beans;
55 using namespace ::com::sun::star::uno;
56 using namespace ::com::sun::star::lang;
57 using namespace ::com::sun::star::awt;
58 using namespace ::com::sun::star::io;
59 using namespace ::com::sun::star::container;
60 using namespace ::com::sun::star::util;
61 using namespace ::osl;
62 using namespace ::comphelper;
63 using namespace ::cppu;
65 DBG_NAME(OColumn)
67 //============================================================
68 //= OColumn
69 //============================================================
70 OColumn::OColumn( const bool _bNameIsReadOnly )
71 :OColumnBase( m_aMutex )
72 ,::comphelper::OPropertyContainer( OColumnBase::rBHelper )
74 DBG_CTOR(OColumn, NULL);
76 registerProperty( PROPERTY_NAME, PROPERTY_ID_NAME, _bNameIsReadOnly ? PropertyAttribute::READONLY : 0,
77 &m_sName, ::getCppuType( &m_sName ) );
80 OColumn::~OColumn()
82 DBG_DTOR(OColumn, NULL);
85 // com::sun::star::lang::XTypeProvider
86 Sequence< Type > OColumn::getTypes() throw (RuntimeException)
88 return ::comphelper::concatSequences(
89 OColumnBase::getTypes(),
90 ::comphelper::OPropertyContainer::getTypes()
94 // com::sun::star::uno::XInterface
95 IMPLEMENT_FORWARD_XINTERFACE2( OColumn, OColumnBase, ::comphelper::OPropertyContainer )
97 // ::com::sun::star::lang::XServiceInfo
98 rtl::OUString OColumn::getImplementationName( ) throw(RuntimeException)
100 return rtl::OUString("com.sun.star.sdb.OColumn");
103 sal_Bool OColumn::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
105 return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
108 Sequence< ::rtl::OUString > OColumn::getSupportedServiceNames( ) throw (RuntimeException)
110 Sequence< ::rtl::OUString > aSNS( 1 );
111 aSNS[0] = SERVICE_SDBCX_COLUMN;
112 return aSNS;
115 // OComponentHelper
116 void OColumn::disposing()
118 OPropertyContainer::disposing();
121 // com::sun::star::beans::XPropertySet
122 Reference< XPropertySetInfo > OColumn::getPropertySetInfo() throw (RuntimeException)
124 return createPropertySetInfo( getInfoHelper() ) ;
127 ::rtl::OUString SAL_CALL OColumn::getName( ) throw(::com::sun::star::uno::RuntimeException)
129 return m_sName;
132 void SAL_CALL OColumn::setName( const ::rtl::OUString& _rName ) throw(::com::sun::star::uno::RuntimeException)
134 m_sName = _rName;
137 void OColumn::fireValueChange(const ::connectivity::ORowSetValue& /*_rOldValue*/)
139 OSL_FAIL( "OColumn::fireValueChange: not implemented!" );
142 void OColumn::registerProperty( const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, void* _pPointerToMember, const Type& _rMemberType )
144 ::comphelper::OPropertyContainer::registerProperty( _rName, _nHandle, _nAttributes, _pPointerToMember, _rMemberType );
147 void OColumn::registerMayBeVoidProperty( const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, Any* _pPointerToMember, const Type& _rExpectedType )
149 ::comphelper::OPropertyContainer::registerMayBeVoidProperty( _rName, _nHandle, _nAttributes, _pPointerToMember, _rExpectedType );
152 void OColumn::registerPropertyNoMember( const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, const Type& _rType, const void* _pInitialValue )
154 ::comphelper::OPropertyContainer::registerPropertyNoMember( _rName, _nHandle, _nAttributes, _rType, _pInitialValue );
157 //============================================================
158 //= OColumns
159 //============================================================
160 DBG_NAME(OColumns);
162 OColumns::OColumns(::cppu::OWeakObject& _rParent,
163 ::osl::Mutex& _rMutex,
164 sal_Bool _bCaseSensitive,const ::std::vector< ::rtl::OUString> &_rVector,
165 IColumnFactory* _pColFactory,
166 ::connectivity::sdbcx::IRefreshableColumns* _pRefresh,
167 sal_Bool _bAddColumn,
168 sal_Bool _bDropColumn,
169 sal_Bool _bUseHardRef)
170 : OColumns_BASE(_rParent,_bCaseSensitive,_rMutex,_rVector,_bUseHardRef)
171 ,m_pMediator(NULL)
172 ,m_xDrvColumns(NULL)
173 ,m_pColFactoryImpl(_pColFactory)
174 ,m_pRefreshColumns(_pRefresh)
175 ,m_bInitialized(sal_False)
176 ,m_bAddColumn(_bAddColumn)
177 ,m_bDropColumn(_bDropColumn)
179 DBG_CTOR(OColumns, NULL);
182 OColumns::OColumns(::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex,
183 const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxDrvColumns,
184 sal_Bool _bCaseSensitive,const ::std::vector< ::rtl::OUString> &_rVector,
185 IColumnFactory* _pColFactory,
186 ::connectivity::sdbcx::IRefreshableColumns* _pRefresh,
187 sal_Bool _bAddColumn,
188 sal_Bool _bDropColumn,
189 sal_Bool _bUseHardRef)
190 : OColumns_BASE(_rParent,_bCaseSensitive,_rMutex,_rVector,_bUseHardRef)
191 ,m_pMediator(NULL)
192 ,m_xDrvColumns(_rxDrvColumns)
193 ,m_pColFactoryImpl(_pColFactory)
194 ,m_pRefreshColumns(_pRefresh)
195 ,m_bInitialized(sal_False)
196 ,m_bAddColumn(_bAddColumn)
197 ,m_bDropColumn(_bDropColumn)
199 DBG_CTOR(OColumns, NULL);
202 OColumns::~OColumns()
204 DBG_DTOR(OColumns, NULL);
207 // XServiceInfo
208 rtl::OUString OColumns::getImplementationName( ) throw(RuntimeException)
210 return rtl::OUString("com.sun.star.sdb.OColumns");
213 sal_Bool OColumns::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
215 return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
218 Sequence< ::rtl::OUString > OColumns::getSupportedServiceNames( ) throw (RuntimeException)
220 Sequence< ::rtl::OUString > aSNS( 1 );
221 aSNS[0] = SERVICE_SDBCX_CONTAINER;
222 return aSNS;
225 //------------------------------------------------------------------
226 void OColumns::append( const ::rtl::OUString& _rName, OColumn* _pColumn )
228 MutexGuard aGuard(m_rMutex);
230 OSL_ENSURE( _pColumn, "OColumns::append: invalid column!" );
231 OSL_ENSURE( !m_pElements->exists( _rName ),"OColumns::append: Column already exists");
233 _pColumn->m_sName = _rName;
235 // now really insert the column
236 insertElement( _rName, _pColumn );
239 //------------------------------------------------------------------
240 void OColumns::clearColumns()
242 MutexGuard aGuard(m_rMutex);
243 disposing();
246 void SAL_CALL OColumns::disposing(void)
248 MutexGuard aGuard(m_rMutex);
249 m_xDrvColumns = NULL;
250 m_pMediator = NULL;
251 m_pColFactoryImpl = NULL;
252 OColumns_BASE::disposing();
255 void OColumns::impl_refresh() throw(::com::sun::star::uno::RuntimeException)
257 if (m_pRefreshColumns)
258 m_pRefreshColumns->refreshColumns();
261 connectivity::sdbcx::ObjectType OColumns::createObject(const ::rtl::OUString& _rName)
263 OSL_ENSURE(m_pColFactoryImpl, "OColumns::createObject: no column factory!");
265 connectivity::sdbcx::ObjectType xRet;
266 if ( m_pColFactoryImpl )
268 xRet = m_pColFactoryImpl->createColumn(_rName);
269 Reference<XChild> xChild(xRet,UNO_QUERY);
270 if ( xChild.is() )
271 xChild->setParent(static_cast<XChild*>(static_cast<TXChild*>(this)));
274 Reference<XPropertySet> xDest(xRet,UNO_QUERY);
275 if ( m_pMediator && xDest.is() )
276 m_pMediator->notifyElementCreated(_rName,xDest);
278 return xRet;
281 Reference< XPropertySet > OColumns::createDescriptor()
283 if ( m_pColFactoryImpl )
285 Reference<XPropertySet> xRet = m_pColFactoryImpl->createColumnDescriptor();
286 Reference<XChild> xChild(xRet,UNO_QUERY);
287 if ( xChild.is() )
288 xChild->setParent(static_cast<XChild*>(static_cast<TXChild*>(this)));
289 return xRet;
291 else
292 return Reference< XPropertySet >();
295 Any SAL_CALL OColumns::queryInterface( const Type & rType ) throw(RuntimeException)
297 Any aRet;
298 if(m_xDrvColumns.is())
300 aRet = m_xDrvColumns->queryInterface(rType);
301 if ( aRet.hasValue() )
302 aRet = OColumns_BASE::queryInterface( rType);
303 if ( !aRet.hasValue() )
304 aRet = TXChild::queryInterface( rType);
305 return aRet;
307 else if(!m_pTable || (m_pTable && !m_pTable->isNew()))
309 if(!m_bAddColumn && rType == getCppuType( (Reference<XAppend>*)0))
310 return Any();
311 if(!m_bDropColumn && rType == getCppuType( (Reference<XDrop>*)0))
312 return Any();
315 aRet = OColumns_BASE::queryInterface( rType);
316 if ( !aRet.hasValue() )
317 aRet = TXChild::queryInterface( rType);
318 return aRet;
321 Sequence< Type > SAL_CALL OColumns::getTypes( ) throw(RuntimeException)
323 sal_Bool bAppendFound = sal_False,bDropFound = sal_False;
325 sal_Int32 nSize = 0;
326 Type aAppendType = getCppuType( (Reference<XAppend>*)0);
327 Type aDropType = getCppuType( (Reference<XDrop>*)0);
328 if(m_xDrvColumns.is())
330 Reference<XTypeProvider> xTypes(m_xDrvColumns,UNO_QUERY);
331 Sequence< Type > aTypes(xTypes->getTypes());
333 Sequence< Type > aSecTypes(OColumns_BASE::getTypes());
336 const Type* pBegin = aTypes.getConstArray();
337 const Type* pEnd = pBegin + aTypes.getLength();
338 for (;pBegin != pEnd ; ++pBegin)
340 if(aAppendType == *pBegin)
341 bAppendFound = sal_True;
342 else if(aDropType == *pBegin)
343 bDropFound = sal_True;
345 nSize = (bDropFound ? (bAppendFound ? 0 : 1) : (bAppendFound ? 1 : 2));
347 else
349 nSize = ((m_pTable && m_pTable->isNew()) ? 0 :
350 ((m_bDropColumn ?
351 (m_bAddColumn ? 0 : 1) : (m_bAddColumn ? 1 : 2))));
352 bDropFound = (m_pTable && m_pTable->isNew()) || m_bDropColumn;
353 bAppendFound = (m_pTable && m_pTable->isNew()) || m_bAddColumn;
355 Sequence< Type > aTypes(::comphelper::concatSequences(OColumns_BASE::getTypes(),TXChild::getTypes()));
356 Sequence< Type > aRet(aTypes.getLength() - nSize);
358 const Type* pBegin = aTypes.getConstArray();
359 const Type* pEnd = pBegin + aTypes.getLength();
360 for(sal_Int32 i=0;pBegin != pEnd ;++pBegin)
362 if(*pBegin != aAppendType && *pBegin != aDropType)
363 aRet.getArray()[i++] = *pBegin;
364 else if(bDropFound && *pBegin == aDropType)
365 aRet.getArray()[i++] = *pBegin;
366 else if(bAppendFound && *pBegin == aAppendType)
367 aRet.getArray()[i++] = *pBegin;
369 return aRet;
372 // XAppend
373 sdbcx::ObjectType OColumns::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
375 sdbcx::ObjectType xReturn;
377 Reference< XAppend > xAppend( m_xDrvColumns, UNO_QUERY );
378 if ( xAppend.is() )
380 xAppend->appendByDescriptor(descriptor);
381 xReturn = createObject( _rForName );
383 else if ( m_pTable && !m_pTable->isNew() )
385 if ( m_bAddColumn )
387 Reference< ::com::sun::star::sdb::tools::XTableAlteration> xAlterService = m_pTable->getAlterService();
388 if ( xAlterService.is() )
390 xAlterService->addColumn(m_pTable,descriptor);
391 xReturn = createObject( _rForName );
393 else
394 xReturn = OColumns_BASE::appendObject( _rForName, descriptor );
396 else
397 ::dbtools::throwGenericSQLException( DBA_RES( RID_STR_NO_COLUMN_ADD ), static_cast<XChild*>(static_cast<TXChild*>(this)) );
399 else
400 xReturn = cloneDescriptor( descriptor );
402 if ( m_pColFactoryImpl )
403 m_pColFactoryImpl->columnAppended( descriptor );
405 ::dbaccess::notifyDataSourceModified(m_xParent,sal_True);
407 return xReturn;
410 // XDrop
411 void OColumns::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
413 Reference< XDrop > xDrop( m_xDrvColumns, UNO_QUERY );
414 if ( xDrop.is() )
416 xDrop->dropByName( _sElementName );
418 else if ( m_pTable && !m_pTable->isNew() )
420 if ( m_bDropColumn )
422 Reference< ::com::sun::star::sdb::tools::XTableAlteration> xAlterService = m_pTable->getAlterService();
423 if ( xAlterService.is() )
424 xAlterService->dropColumn(m_pTable,_sElementName);
425 else
426 OColumns_BASE::dropObject(_nPos,_sElementName);
428 else
429 ::dbtools::throwGenericSQLException( DBA_RES( RID_STR_NO_COLUMN_DROP ), static_cast<XChild*>(static_cast<TXChild*>(this)) );
432 if ( m_pColFactoryImpl )
433 m_pColFactoryImpl->columnDropped(_sElementName);
435 ::dbaccess::notifyDataSourceModified(m_xParent,sal_True);
438 Reference< XInterface > SAL_CALL OColumns::getParent( ) throw (RuntimeException)
440 ::osl::MutexGuard aGuard(m_rMutex);
441 return m_xParent;
444 void SAL_CALL OColumns::setParent( const Reference< XInterface >& _xParent ) throw (NoSupportException, RuntimeException)
446 ::osl::MutexGuard aGuard(m_rMutex);
447 m_xParent = _xParent;
449 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */