xref: /AOO41X/main/dbaccess/source/core/api/column.cxx (revision 96de54900b79e13b861fbc62cbf36018b54e21b7)
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 #include "ContainerMediator.hxx"
28 #include "apitools.hxx"
29 #include "column.hxx"
30 #include "core_resource.hrc"
31 #include "core_resource.hxx"
32 #include "dbastrings.hrc"
33 #include "sdbcoretools.hxx"
34 
35 #include <com/sun/star/lang/DisposedException.hpp>
36 #include <com/sun/star/sdbc/ColumnValue.hpp>
37 #include <com/sun/star/sdbc/DataType.hpp>
38 
39 #include <comphelper/basicio.hxx>
40 #include <comphelper/enumhelper.hxx>
41 #include <comphelper/extract.hxx>
42 #include <comphelper/property.hxx>
43 #include <comphelper/seqstream.hxx>
44 #include <comphelper/sequence.hxx>
45 #include <comphelper/types.hxx>
46 #include <connectivity/TTableHelper.hxx>
47 #include <connectivity/dbexception.hxx>
48 #include <connectivity/dbtools.hxx>
49 #include <cppuhelper/typeprovider.hxx>
50 #include <osl/diagnose.h>
51 #include <tools/debug.hxx>
52 
53 #include <algorithm>
54 
55 using namespace dbaccess;
56 using namespace connectivity;
57 using namespace connectivity;
58 using namespace ::com::sun::star::sdbc;
59 using namespace ::com::sun::star::sdbcx;
60 using namespace ::com::sun::star::beans;
61 using namespace ::com::sun::star::uno;
62 using namespace ::com::sun::star::lang;
63 using namespace ::com::sun::star::awt;
64 using namespace ::com::sun::star::io;
65 using namespace ::com::sun::star::container;
66 using namespace ::com::sun::star::util;
67 using namespace ::osl;
68 using namespace ::comphelper;
69 using namespace ::cppu;
70 
DBG_NAME(OColumn)71 DBG_NAME(OColumn)
72 
73 //============================================================
74 //= OColumn
75 //============================================================
76 //--------------------------------------------------------------------------
77 OColumn::OColumn( const bool _bNameIsReadOnly )
78         :OColumnBase( m_aMutex )
79         ,::comphelper::OPropertyContainer( OColumnBase::rBHelper )
80 {
81     DBG_CTOR(OColumn, NULL);
82 
83     registerProperty( PROPERTY_NAME, PROPERTY_ID_NAME, _bNameIsReadOnly ? PropertyAttribute::READONLY : 0,
84         &m_sName, ::getCppuType( &m_sName ) );
85 }
86 
87 //--------------------------------------------------------------------------
~OColumn()88 OColumn::~OColumn()
89 {
90     DBG_DTOR(OColumn, NULL);
91 }
92 
93 // com::sun::star::lang::XTypeProvider
94 //--------------------------------------------------------------------------
getTypes()95 Sequence< Type > OColumn::getTypes() throw (RuntimeException)
96 {
97     return ::comphelper::concatSequences(
98         OColumnBase::getTypes(),
99         ::comphelper::OPropertyContainer::getTypes()
100     );
101 }
102 
103 // com::sun::star::uno::XInterface
IMPLEMENT_FORWARD_XINTERFACE2(OColumn,OColumnBase,::comphelper::OPropertyContainer)104 IMPLEMENT_FORWARD_XINTERFACE2( OColumn, OColumnBase, ::comphelper::OPropertyContainer )
105 
106 // ::com::sun::star::lang::XServiceInfo
107 //------------------------------------------------------------------------------
108 rtl::OUString OColumn::getImplementationName(  ) throw(RuntimeException)
109 {
110     return rtl::OUString::createFromAscii("com.sun.star.sdb.OColumn");
111 }
112 
113 //------------------------------------------------------------------------------
supportsService(const::rtl::OUString & _rServiceName)114 sal_Bool OColumn::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
115 {
116     return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
117 }
118 
119 //------------------------------------------------------------------------------
getSupportedServiceNames()120 Sequence< ::rtl::OUString > OColumn::getSupportedServiceNames(  ) throw (RuntimeException)
121 {
122     Sequence< ::rtl::OUString > aSNS( 1 );
123     aSNS[0] = SERVICE_SDBCX_COLUMN;
124     return aSNS;
125 }
126 
127 // OComponentHelper
128 //------------------------------------------------------------------------------
disposing()129 void OColumn::disposing()
130 {
131     OPropertyContainer::disposing();
132 }
133 
134 // com::sun::star::beans::XPropertySet
135 //------------------------------------------------------------------------------
getPropertySetInfo()136 Reference< XPropertySetInfo > OColumn::getPropertySetInfo() throw (RuntimeException)
137 {
138     return createPropertySetInfo( getInfoHelper() ) ;
139 }
140 
141 // -----------------------------------------------------------------------------
getName()142 ::rtl::OUString SAL_CALL OColumn::getName(  ) throw(::com::sun::star::uno::RuntimeException)
143 {
144     return m_sName;
145 }
146 // -----------------------------------------------------------------------------
setName(const::rtl::OUString & _rName)147 void SAL_CALL OColumn::setName( const ::rtl::OUString& _rName ) throw(::com::sun::star::uno::RuntimeException)
148 {
149     m_sName = _rName;
150 }
151 
152 // -----------------------------------------------------------------------------
fireValueChange(const::connectivity::ORowSetValue &)153 void OColumn::fireValueChange(const ::connectivity::ORowSetValue& /*_rOldValue*/)
154 {
155     DBG_ERROR( "OColumn::fireValueChange: not implemented!" );
156 }
157 
158 //------------------------------------------------------------------------------
registerProperty(const::rtl::OUString & _rName,sal_Int32 _nHandle,sal_Int32 _nAttributes,void * _pPointerToMember,const Type & _rMemberType)159 void OColumn::registerProperty( const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, void* _pPointerToMember, const Type& _rMemberType )
160 {
161     ::comphelper::OPropertyContainer::registerProperty( _rName, _nHandle, _nAttributes, _pPointerToMember, _rMemberType );
162 }
163 
164 //------------------------------------------------------------------------------
registerMayBeVoidProperty(const::rtl::OUString & _rName,sal_Int32 _nHandle,sal_Int32 _nAttributes,Any * _pPointerToMember,const Type & _rExpectedType)165 void OColumn::registerMayBeVoidProperty( const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, Any* _pPointerToMember, const Type& _rExpectedType )
166 {
167     ::comphelper::OPropertyContainer::registerMayBeVoidProperty( _rName, _nHandle, _nAttributes, _pPointerToMember, _rExpectedType );
168 }
169 
170 //------------------------------------------------------------------------------
registerPropertyNoMember(const::rtl::OUString & _rName,sal_Int32 _nHandle,sal_Int32 _nAttributes,const Type & _rType,const void * _pInitialValue)171 void OColumn::registerPropertyNoMember( const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, const Type& _rType, const void* _pInitialValue )
172 {
173     ::comphelper::OPropertyContainer::registerPropertyNoMember( _rName, _nHandle, _nAttributes, _rType, _pInitialValue );
174 }
175 
176 //============================================================
177 //= OColumns
178 //============================================================
179 DBG_NAME(OColumns);
180 
181 //--------------------------------------------------------------------------
OColumns(::cppu::OWeakObject & _rParent,::osl::Mutex & _rMutex,sal_Bool _bCaseSensitive,const::std::vector<::rtl::OUString> & _rVector,IColumnFactory * _pColFactory,::connectivity::sdbcx::IRefreshableColumns * _pRefresh,sal_Bool _bAddColumn,sal_Bool _bDropColumn,sal_Bool _bUseHardRef)182 OColumns::OColumns(::cppu::OWeakObject& _rParent,
183                    ::osl::Mutex& _rMutex,
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(NULL)
193     ,m_pColFactoryImpl(_pColFactory)
194     ,m_pRefreshColumns(_pRefresh)
195     ,m_bInitialized(sal_False)
196     ,m_bAddColumn(_bAddColumn)
197     ,m_bDropColumn(_bDropColumn)
198 {
199     DBG_CTOR(OColumns, NULL);
200 }
201 
202 // -------------------------------------------------------------------------
OColumns(::cppu::OWeakObject & _rParent,::osl::Mutex & _rMutex,const::com::sun::star::uno::Reference<::com::sun::star::container::XNameAccess> & _rxDrvColumns,sal_Bool _bCaseSensitive,const::std::vector<::rtl::OUString> & _rVector,IColumnFactory * _pColFactory,::connectivity::sdbcx::IRefreshableColumns * _pRefresh,sal_Bool _bAddColumn,sal_Bool _bDropColumn,sal_Bool _bUseHardRef)203 OColumns::OColumns(::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex,
204         const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxDrvColumns,
205         sal_Bool _bCaseSensitive,const ::std::vector< ::rtl::OUString> &_rVector,
206         IColumnFactory* _pColFactory,
207         ::connectivity::sdbcx::IRefreshableColumns* _pRefresh,
208         sal_Bool _bAddColumn,
209         sal_Bool _bDropColumn,
210         sal_Bool _bUseHardRef)
211        : OColumns_BASE(_rParent,_bCaseSensitive,_rMutex,_rVector,_bUseHardRef)
212     ,m_pMediator(NULL)
213     ,m_xDrvColumns(_rxDrvColumns)
214     ,m_pColFactoryImpl(_pColFactory)
215     ,m_pRefreshColumns(_pRefresh)
216     ,m_bInitialized(sal_False)
217     ,m_bAddColumn(_bAddColumn)
218     ,m_bDropColumn(_bDropColumn)
219 {
220     DBG_CTOR(OColumns, NULL);
221 }
222 //--------------------------------------------------------------------------
~OColumns()223 OColumns::~OColumns()
224 {
225     DBG_DTOR(OColumns, NULL);
226 }
227 
228 // XServiceInfo
229 //------------------------------------------------------------------------------
getImplementationName()230 rtl::OUString OColumns::getImplementationName(  ) throw(RuntimeException)
231 {
232     return rtl::OUString::createFromAscii("com.sun.star.sdb.OColumns");
233 }
234 
235 //------------------------------------------------------------------------------
supportsService(const::rtl::OUString & _rServiceName)236 sal_Bool OColumns::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
237 {
238     return ::comphelper::findValue(getSupportedServiceNames(), _rServiceName, sal_True).getLength() != 0;
239 }
240 
241 //------------------------------------------------------------------------------
getSupportedServiceNames()242 Sequence< ::rtl::OUString > OColumns::getSupportedServiceNames(  ) throw (RuntimeException)
243 {
244     Sequence< ::rtl::OUString > aSNS( 1 );
245     aSNS[0] = SERVICE_SDBCX_CONTAINER;
246     return aSNS;
247 }
248 
249 //------------------------------------------------------------------
append(const::rtl::OUString & _rName,OColumn * _pColumn)250 void OColumns::append( const ::rtl::OUString& _rName, OColumn* _pColumn )
251 {
252     MutexGuard aGuard(m_rMutex);
253 
254     OSL_ENSURE( _pColumn, "OColumns::append: invalid column!" );
255     OSL_ENSURE( !m_pElements->exists( _rName ),"OColumns::append: Column already exists");
256 
257     _pColumn->m_sName = _rName;
258 
259     // now really insert the column
260     insertElement( _rName, _pColumn );
261 }
262 
263 //------------------------------------------------------------------
clearColumns()264 void OColumns::clearColumns()
265 {
266     MutexGuard aGuard(m_rMutex);
267     disposing();
268 }
269 
270 // -----------------------------------------------------------------------------
disposing(void)271 void SAL_CALL OColumns::disposing(void)
272 {
273     MutexGuard aGuard(m_rMutex);
274     m_xDrvColumns = NULL;
275     m_pMediator = NULL;
276     m_pColFactoryImpl = NULL;
277     OColumns_BASE::disposing();
278 }
279 
280 // -------------------------------------------------------------------------
impl_refresh()281 void OColumns::impl_refresh() throw(::com::sun::star::uno::RuntimeException)
282 {
283     if (m_pRefreshColumns)
284         m_pRefreshColumns->refreshColumns();
285 }
286 
287 // -------------------------------------------------------------------------
createObject(const::rtl::OUString & _rName)288 connectivity::sdbcx::ObjectType OColumns::createObject(const ::rtl::OUString& _rName)
289 {
290     OSL_ENSURE(m_pColFactoryImpl, "OColumns::createObject: no column factory!");
291 
292     connectivity::sdbcx::ObjectType xRet;
293     if ( m_pColFactoryImpl )
294     {
295         xRet = m_pColFactoryImpl->createColumn(_rName);
296         Reference<XChild> xChild(xRet,UNO_QUERY);
297         if ( xChild.is() )
298             xChild->setParent(static_cast<XChild*>(static_cast<TXChild*>(this)));
299     }
300 
301     Reference<XPropertySet> xDest(xRet,UNO_QUERY);
302     if ( m_pMediator && xDest.is() )
303         m_pMediator->notifyElementCreated(_rName,xDest);
304 
305     return xRet;
306 }
307 // -------------------------------------------------------------------------
createDescriptor()308 Reference< XPropertySet > OColumns::createDescriptor()
309 {
310     if ( m_pColFactoryImpl )
311     {
312         Reference<XPropertySet> xRet = m_pColFactoryImpl->createColumnDescriptor();
313         Reference<XChild> xChild(xRet,UNO_QUERY);
314         if ( xChild.is() )
315             xChild->setParent(static_cast<XChild*>(static_cast<TXChild*>(this)));
316         return xRet;
317     }
318     else
319         return Reference< XPropertySet >();
320 }
321 // -------------------------------------------------------------------------
queryInterface(const Type & rType)322 Any SAL_CALL OColumns::queryInterface( const Type & rType ) throw(RuntimeException)
323 {
324     Any aRet;
325     if(m_xDrvColumns.is())
326     {
327         aRet = m_xDrvColumns->queryInterface(rType);
328         if ( aRet.hasValue() )
329             aRet = OColumns_BASE::queryInterface( rType);
330         if ( !aRet.hasValue() )
331             aRet = TXChild::queryInterface( rType);
332         return aRet;
333     }
334     else if(!m_pTable || (m_pTable && !m_pTable->isNew()))
335     {
336         if(!m_bAddColumn    && rType == getCppuType( (Reference<XAppend>*)0))
337             return Any();
338         if(!m_bDropColumn   && rType == getCppuType( (Reference<XDrop>*)0))
339             return Any();
340     }
341 
342     aRet = OColumns_BASE::queryInterface( rType);
343     if ( !aRet.hasValue() )
344         aRet = TXChild::queryInterface( rType);
345     return aRet;
346 }
347 // -------------------------------------------------------------------------
getTypes()348 Sequence< Type > SAL_CALL OColumns::getTypes(  ) throw(RuntimeException)
349 {
350     sal_Bool bAppendFound = sal_False,bDropFound = sal_False;
351 
352     sal_Int32 nSize = 0;
353     Type aAppendType = getCppuType( (Reference<XAppend>*)0);
354     Type aDropType   = getCppuType( (Reference<XDrop>*)0);
355     if(m_xDrvColumns.is())
356     {
357         Reference<XTypeProvider> xTypes(m_xDrvColumns,UNO_QUERY);
358         Sequence< Type > aTypes(xTypes->getTypes());
359 
360         Sequence< Type > aSecTypes(OColumns_BASE::getTypes());
361 
362 
363         const Type* pBegin = aTypes.getConstArray();
364         const Type* pEnd = pBegin + aTypes.getLength();
365         for (;pBegin != pEnd ; ++pBegin)
366         {
367             if(aAppendType == *pBegin)
368                 bAppendFound = sal_True;
369             else if(aDropType == *pBegin)
370                 bDropFound = sal_True;
371         }
372         nSize = (bDropFound ? (bAppendFound ? 0 : 1) : (bAppendFound ? 1 : 2));
373     }
374     else
375     {
376         nSize = ((m_pTable && m_pTable->isNew()) ? 0 :
377                     ((m_bDropColumn ?
378                         (m_bAddColumn ? 0 : 1) : (m_bAddColumn ? 1 : 2))));
379         bDropFound      = (m_pTable && m_pTable->isNew()) || m_bDropColumn;
380         bAppendFound    = (m_pTable && m_pTable->isNew()) || m_bAddColumn;
381     }
382     Sequence< Type > aTypes(::comphelper::concatSequences(OColumns_BASE::getTypes(),TXChild::getTypes()));
383     Sequence< Type > aRet(aTypes.getLength() - nSize);
384 
385     const Type* pBegin = aTypes.getConstArray();
386     const Type* pEnd = pBegin + aTypes.getLength();
387     for(sal_Int32 i=0;pBegin != pEnd ;++pBegin)
388     {
389         if(*pBegin != aAppendType && *pBegin != aDropType)
390             aRet.getArray()[i++] = *pBegin;
391         else if(bDropFound && *pBegin == aDropType)
392             aRet.getArray()[i++] = *pBegin;
393         else if(bAppendFound && *pBegin == aAppendType)
394             aRet.getArray()[i++] = *pBegin;
395     }
396     return aRet;
397 }
398 // -------------------------------------------------------------------------
399 // XAppend
appendObject(const::rtl::OUString & _rForName,const Reference<XPropertySet> & descriptor)400 sdbcx::ObjectType OColumns::appendObject( const ::rtl::OUString& _rForName, const Reference< XPropertySet >& descriptor )
401 {
402     sdbcx::ObjectType xReturn;
403 
404     Reference< XAppend > xAppend( m_xDrvColumns, UNO_QUERY );
405     if ( xAppend.is() )
406     {
407         xAppend->appendByDescriptor(descriptor);
408         xReturn = createObject( _rForName );
409     }
410     else if ( m_pTable && !m_pTable->isNew() )
411     {
412         if ( m_bAddColumn )
413         {
414             Reference< ::com::sun::star::sdb::tools::XTableAlteration> xAlterService = m_pTable->getAlterService();
415             if ( xAlterService.is() )
416             {
417                 xAlterService->addColumn(m_pTable,descriptor);
418                 xReturn = createObject( _rForName );
419             }
420             else
421                 xReturn = OColumns_BASE::appendObject( _rForName, descriptor );
422         }
423         else
424             ::dbtools::throwGenericSQLException( DBA_RES( RID_STR_NO_COLUMN_ADD ), static_cast<XChild*>(static_cast<TXChild*>(this)) );
425     }
426     else
427         xReturn = cloneDescriptor( descriptor );
428 
429     if ( m_pColFactoryImpl )
430         m_pColFactoryImpl->columnAppended( descriptor );
431 
432     ::dbaccess::notifyDataSourceModified(m_xParent,sal_True);
433 
434     return xReturn;
435 }
436 // -------------------------------------------------------------------------
437 // XDrop
dropObject(sal_Int32 _nPos,const::rtl::OUString _sElementName)438 void OColumns::dropObject(sal_Int32 _nPos,const ::rtl::OUString _sElementName)
439 {
440     Reference< XDrop > xDrop( m_xDrvColumns, UNO_QUERY );
441     if ( xDrop.is() )
442     {
443         xDrop->dropByName( _sElementName );
444     }
445     else if ( m_pTable && !m_pTable->isNew() )
446     {
447         if ( m_bDropColumn )
448         {
449             Reference< ::com::sun::star::sdb::tools::XTableAlteration> xAlterService = m_pTable->getAlterService();
450             if ( xAlterService.is() )
451                 xAlterService->dropColumn(m_pTable,_sElementName);
452             else
453                 OColumns_BASE::dropObject(_nPos,_sElementName);
454         }
455         else
456             ::dbtools::throwGenericSQLException( DBA_RES( RID_STR_NO_COLUMN_DROP ), static_cast<XChild*>(static_cast<TXChild*>(this)) );
457     }
458 
459     if ( m_pColFactoryImpl )
460         m_pColFactoryImpl->columnDropped(_sElementName);
461 
462     ::dbaccess::notifyDataSourceModified(m_xParent,sal_True);
463 }
464 // -----------------------------------------------------------------------------
465 
getParent()466 Reference< XInterface > SAL_CALL OColumns::getParent(  ) throw (RuntimeException)
467 {
468     ::osl::MutexGuard aGuard(m_rMutex);
469     return m_xParent;
470 }
471 // -----------------------------------------------------------------------------
setParent(const Reference<XInterface> & _xParent)472 void SAL_CALL OColumns::setParent( const Reference< XInterface >& _xParent ) throw (NoSupportException, RuntimeException)
473 {
474     ::osl::MutexGuard aGuard(m_rMutex);
475     m_xParent = _xParent;
476 }
477 // -----------------------------------------------------------------------------
478