Bump version to 5.0-14
[LibreOffice.git] / dbaccess / source / core / api / column.cxx
blobca0ee700413c761a4e5116b6502cd0940d2d1718
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 .
20 #include "ContainerMediator.hxx"
21 #include "apitools.hxx"
22 #include "column.hxx"
23 #include "core_resource.hrc"
24 #include "core_resource.hxx"
25 #include "dbastrings.hrc"
26 #include "sdbcoretools.hxx"
28 #include <com/sun/star/lang/DisposedException.hpp>
29 #include <com/sun/star/sdbc/ColumnValue.hpp>
30 #include <com/sun/star/sdbc/DataType.hpp>
32 #include <comphelper/enumhelper.hxx>
33 #include <comphelper/extract.hxx>
34 #include <comphelper/property.hxx>
35 #include <comphelper/seqstream.hxx>
36 #include <comphelper/sequence.hxx>
37 #include <comphelper/types.hxx>
38 #include <connectivity/TTableHelper.hxx>
39 #include <connectivity/dbexception.hxx>
40 #include <connectivity/dbtools.hxx>
41 #include <cppuhelper/supportsservice.hxx>
42 #include <cppuhelper/typeprovider.hxx>
43 #include <osl/diagnose.h>
44 #include <tools/debug.hxx>
46 #include <algorithm>
48 using namespace dbaccess;
49 using namespace connectivity;
50 using namespace ::com::sun::star::sdbc;
51 using namespace ::com::sun::star::sdbcx;
52 using namespace ::com::sun::star::beans;
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::lang;
55 using namespace ::com::sun::star::awt;
56 using namespace ::com::sun::star::io;
57 using namespace ::com::sun::star::container;
58 using namespace ::com::sun::star::util;
59 using namespace ::osl;
60 using namespace ::comphelper;
61 using namespace ::cppu;
64 // OColumn
65 OColumn::OColumn( const bool _bNameIsReadOnly )
66 :OColumnBase( m_aMutex )
67 ,::comphelper::OPropertyContainer( OColumnBase::rBHelper )
70 registerProperty( PROPERTY_NAME, PROPERTY_ID_NAME, _bNameIsReadOnly ? PropertyAttribute::READONLY : 0,
71 &m_sName, cppu::UnoType<decltype(m_sName)>::get() );
74 OColumn::~OColumn()
78 // com::sun::star::lang::XTypeProvider
79 Sequence< Type > OColumn::getTypes() throw (RuntimeException, std::exception)
81 return ::comphelper::concatSequences(
82 OColumnBase::getTypes(),
83 getBaseTypes()
87 // com::sun::star::uno::XInterface
88 IMPLEMENT_FORWARD_XINTERFACE2( OColumn, OColumnBase, ::comphelper::OPropertyContainer )
90 // ::com::sun::star::lang::XServiceInfo
91 OUString OColumn::getImplementationName( ) throw(RuntimeException, std::exception)
93 return OUString("com.sun.star.sdb.OColumn");
96 sal_Bool OColumn::supportsService( const OUString& _rServiceName ) throw (RuntimeException, std::exception)
98 return cppu::supportsService(this, _rServiceName);
101 Sequence< OUString > OColumn::getSupportedServiceNames( ) throw (RuntimeException, std::exception)
103 Sequence< OUString > aSNS( 1 );
104 aSNS[0] = SERVICE_SDBCX_COLUMN;
105 return aSNS;
108 // OComponentHelper
109 void OColumn::disposing()
111 OPropertyContainer::disposing();
114 // com::sun::star::beans::XPropertySet
115 Reference< XPropertySetInfo > OColumn::getPropertySetInfo() throw (RuntimeException, std::exception)
117 return createPropertySetInfo( getInfoHelper() ) ;
120 OUString SAL_CALL OColumn::getName( ) throw(::com::sun::star::uno::RuntimeException, std::exception)
122 return m_sName;
125 void SAL_CALL OColumn::setName( const OUString& _rName ) throw(::com::sun::star::uno::RuntimeException, std::exception)
127 m_sName = _rName;
130 void OColumn::fireValueChange(const ::connectivity::ORowSetValue& /*_rOldValue*/)
132 OSL_FAIL( "OColumn::fireValueChange: not implemented!" );
135 void OColumn::registerProperty( const OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, void* _pPointerToMember, const Type& _rMemberType )
137 ::comphelper::OPropertyContainer::registerProperty( _rName, _nHandle, _nAttributes, _pPointerToMember, _rMemberType );
140 void OColumn::registerMayBeVoidProperty( const OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, Any* _pPointerToMember, const Type& _rExpectedType )
142 ::comphelper::OPropertyContainer::registerMayBeVoidProperty( _rName, _nHandle, _nAttributes, _pPointerToMember, _rExpectedType );
145 void OColumn::registerPropertyNoMember( const OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, const Type& _rType, const void* _pInitialValue )
147 ::comphelper::OPropertyContainer::registerPropertyNoMember( _rName, _nHandle, _nAttributes, _rType, _pInitialValue );
150 // OColumns
152 OColumns::OColumns(::cppu::OWeakObject& _rParent,
153 ::osl::Mutex& _rMutex,
154 bool _bCaseSensitive,const ::std::vector< OUString> &_rVector,
155 IColumnFactory* _pColFactory,
156 ::connectivity::sdbcx::IRefreshableColumns* _pRefresh,
157 bool _bAddColumn,
158 bool _bDropColumn,
159 bool _bUseHardRef)
160 : OColumns_BASE(_rParent,_bCaseSensitive,_rMutex,_rVector,_bUseHardRef)
161 ,m_pMediator(NULL)
162 ,m_xDrvColumns(NULL)
163 ,m_pColFactoryImpl(_pColFactory)
164 ,m_pRefreshColumns(_pRefresh)
165 ,m_bInitialized(false)
166 ,m_bAddColumn(_bAddColumn)
167 ,m_bDropColumn(_bDropColumn)
171 OColumns::OColumns(::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex,
172 const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxDrvColumns,
173 bool _bCaseSensitive,const ::std::vector< OUString> &_rVector,
174 IColumnFactory* _pColFactory,
175 ::connectivity::sdbcx::IRefreshableColumns* _pRefresh,
176 bool _bAddColumn,
177 bool _bDropColumn,
178 bool _bUseHardRef)
179 : OColumns_BASE(_rParent,_bCaseSensitive,_rMutex,_rVector,_bUseHardRef)
180 ,m_pMediator(NULL)
181 ,m_xDrvColumns(_rxDrvColumns)
182 ,m_pColFactoryImpl(_pColFactory)
183 ,m_pRefreshColumns(_pRefresh)
184 ,m_bInitialized(false)
185 ,m_bAddColumn(_bAddColumn)
186 ,m_bDropColumn(_bDropColumn)
190 OColumns::~OColumns()
194 // XServiceInfo
195 OUString OColumns::getImplementationName( ) throw(RuntimeException, std::exception)
197 return OUString("com.sun.star.sdb.OColumns");
200 sal_Bool OColumns::supportsService( const OUString& _rServiceName ) throw (RuntimeException, std::exception)
202 return cppu::supportsService(this, _rServiceName);
205 Sequence< OUString > OColumns::getSupportedServiceNames( ) throw (RuntimeException, std::exception)
207 Sequence< OUString > aSNS( 1 );
208 aSNS[0] = SERVICE_SDBCX_CONTAINER;
209 return aSNS;
212 void OColumns::append( const OUString& _rName, OColumn* _pColumn )
214 MutexGuard aGuard(m_rMutex);
216 OSL_ENSURE( _pColumn, "OColumns::append: invalid column!" );
217 OSL_ENSURE( !m_pElements->exists( _rName ),"OColumns::append: Column already exists");
219 _pColumn->m_sName = _rName;
221 // now really insert the column
222 insertElement( _rName, _pColumn );
225 void OColumns::clearColumns()
227 MutexGuard aGuard(m_rMutex);
228 disposing();
231 void SAL_CALL OColumns::disposing()
233 MutexGuard aGuard(m_rMutex);
234 m_xDrvColumns = NULL;
235 m_pMediator = NULL;
236 m_pColFactoryImpl = NULL;
237 OColumns_BASE::disposing();
240 void OColumns::impl_refresh() throw(::com::sun::star::uno::RuntimeException)
242 if (m_pRefreshColumns)
243 m_pRefreshColumns->refreshColumns();
246 connectivity::sdbcx::ObjectType OColumns::createObject(const OUString& _rName)
248 OSL_ENSURE(m_pColFactoryImpl, "OColumns::createObject: no column factory!");
250 connectivity::sdbcx::ObjectType xRet;
251 if ( m_pColFactoryImpl )
253 xRet = m_pColFactoryImpl->createColumn(_rName);
254 Reference<XChild> xChild(xRet,UNO_QUERY);
255 if ( xChild.is() )
256 xChild->setParent(static_cast<XChild*>(static_cast<TXChild*>(this)));
259 Reference<XPropertySet> xDest(xRet,UNO_QUERY);
260 if ( m_pMediator && xDest.is() )
261 m_pMediator->notifyElementCreated(_rName,xDest);
263 return xRet;
266 Reference< XPropertySet > OColumns::createDescriptor()
268 if ( m_pColFactoryImpl )
270 Reference<XPropertySet> xRet = m_pColFactoryImpl->createColumnDescriptor();
271 Reference<XChild> xChild(xRet,UNO_QUERY);
272 if ( xChild.is() )
273 xChild->setParent(static_cast<XChild*>(static_cast<TXChild*>(this)));
274 return xRet;
276 else
277 return Reference< XPropertySet >();
280 Any SAL_CALL OColumns::queryInterface( const Type & rType ) throw(RuntimeException, std::exception)
282 Any aRet;
283 if(m_xDrvColumns.is())
285 aRet = m_xDrvColumns->queryInterface(rType);
286 if ( aRet.hasValue() )
287 aRet = OColumns_BASE::queryInterface( rType);
288 if ( !aRet.hasValue() )
289 aRet = TXChild::queryInterface( rType);
290 return aRet;
292 else if(!m_pTable || (m_pTable && !m_pTable->isNew()))
294 if(!m_bAddColumn && rType == cppu::UnoType<XAppend>::get())
295 return Any();
296 if(!m_bDropColumn && rType == cppu::UnoType<XDrop>::get())
297 return Any();
300 aRet = OColumns_BASE::queryInterface( rType);
301 if ( !aRet.hasValue() )
302 aRet = TXChild::queryInterface( rType);
303 return aRet;
306 Sequence< Type > SAL_CALL OColumns::getTypes( ) throw(RuntimeException, std::exception)
308 bool bAppendFound = false,bDropFound = false;
310 sal_Int32 nSize = 0;
311 Type aAppendType = cppu::UnoType<XAppend>::get();
312 Type aDropType = cppu::UnoType<XDrop>::get();
313 if(m_xDrvColumns.is())
315 Reference<XTypeProvider> xTypes(m_xDrvColumns,UNO_QUERY);
316 Sequence< Type > aTypes(xTypes->getTypes());
318 const Type* pBegin = aTypes.getConstArray();
319 const Type* pEnd = pBegin + aTypes.getLength();
320 for (;pBegin != pEnd ; ++pBegin)
322 if(aAppendType == *pBegin)
323 bAppendFound = true;
324 else if(aDropType == *pBegin)
325 bDropFound = true;
327 nSize = (bDropFound ? (bAppendFound ? 0 : 1) : (bAppendFound ? 1 : 2));
329 else
331 nSize = ((m_pTable && m_pTable->isNew()) ? 0 :
332 ((m_bDropColumn ?
333 (m_bAddColumn ? 0 : 1) : (m_bAddColumn ? 1 : 2))));
334 bDropFound = (m_pTable && m_pTable->isNew()) || m_bDropColumn;
335 bAppendFound = (m_pTable && m_pTable->isNew()) || m_bAddColumn;
337 Sequence< Type > aTypes(::comphelper::concatSequences(OColumns_BASE::getTypes(),TXChild::getTypes()));
338 Sequence< Type > aRet(aTypes.getLength() - nSize);
340 const Type* pBegin = aTypes.getConstArray();
341 const Type* pEnd = pBegin + aTypes.getLength();
342 for(sal_Int32 i=0;pBegin != pEnd ;++pBegin)
344 if(*pBegin != aAppendType && *pBegin != aDropType)
345 aRet.getArray()[i++] = *pBegin;
346 else if(bDropFound && *pBegin == aDropType)
347 aRet.getArray()[i++] = *pBegin;
348 else if(bAppendFound && *pBegin == aAppendType)
349 aRet.getArray()[i++] = *pBegin;
351 return aRet;
354 // XAppend
355 sdbcx::ObjectType OColumns::appendObject( const OUString& _rForName, const Reference< XPropertySet >& descriptor )
357 sdbcx::ObjectType xReturn;
359 Reference< XAppend > xAppend( m_xDrvColumns, UNO_QUERY );
360 if ( xAppend.is() )
362 xAppend->appendByDescriptor(descriptor);
363 xReturn = createObject( _rForName );
365 else if ( m_pTable && !m_pTable->isNew() )
367 if ( m_bAddColumn )
369 Reference< ::com::sun::star::sdb::tools::XTableAlteration> xAlterService = m_pTable->getAlterService();
370 if ( xAlterService.is() )
372 xAlterService->addColumn(m_pTable,descriptor);
373 xReturn = createObject( _rForName );
375 else
376 xReturn = OColumns_BASE::appendObject( _rForName, descriptor );
378 else
379 ::dbtools::throwGenericSQLException( DBA_RES( RID_STR_NO_COLUMN_ADD ), static_cast<XChild*>(static_cast<TXChild*>(this)) );
381 else
382 xReturn = cloneDescriptor( descriptor );
384 if ( m_pColFactoryImpl )
385 m_pColFactoryImpl->columnAppended( descriptor );
387 ::dbaccess::notifyDataSourceModified(m_xParent,true);
389 return xReturn;
392 // XDrop
393 void OColumns::dropObject(sal_Int32 _nPos, const OUString& _sElementName)
395 Reference< XDrop > xDrop( m_xDrvColumns, UNO_QUERY );
396 if ( xDrop.is() )
398 xDrop->dropByName( _sElementName );
400 else if ( m_pTable && !m_pTable->isNew() )
402 if ( m_bDropColumn )
404 Reference< ::com::sun::star::sdb::tools::XTableAlteration> xAlterService = m_pTable->getAlterService();
405 if ( xAlterService.is() )
406 xAlterService->dropColumn(m_pTable,_sElementName);
407 else
408 OColumns_BASE::dropObject(_nPos,_sElementName);
410 else
411 ::dbtools::throwGenericSQLException( DBA_RES( RID_STR_NO_COLUMN_DROP ), static_cast<XChild*>(static_cast<TXChild*>(this)) );
414 if ( m_pColFactoryImpl )
415 m_pColFactoryImpl->columnDropped(_sElementName);
417 ::dbaccess::notifyDataSourceModified(m_xParent,true);
420 Reference< XInterface > SAL_CALL OColumns::getParent( ) throw (RuntimeException, std::exception)
422 ::osl::MutexGuard aGuard(m_rMutex);
423 return m_xParent;
426 void SAL_CALL OColumns::setParent( const Reference< XInterface >& _xParent ) throw (NoSupportException, RuntimeException, std::exception)
428 ::osl::MutexGuard aGuard(m_rMutex);
429 m_xParent = _xParent;
432 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */