LibreOffice Module dbaccess (master) 1
column.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <ContainerMediator.hxx>
21#include <column.hxx>
22#include <strings.hrc>
23#include <strings.hxx>
24#include <core_resource.hxx>
25#include <stringconstants.hxx>
26#include <sdbcoretools.hxx>
27
28#include <com/sun/star/beans/PropertyAttribute.hpp>
29#include <com/sun/star/sdb/tools/XTableAlteration.hpp>
30
32#include <comphelper/types.hxx>
33#include <comphelper/uno3.hxx>
37#include <utility>
38#include <osl/diagnose.h>
39
40using namespace dbaccess;
41using namespace connectivity;
42using namespace ::com::sun::star::sdbc;
43using namespace ::com::sun::star::sdbcx;
44using namespace ::com::sun::star::beans;
45using namespace ::com::sun::star::uno;
46using namespace ::com::sun::star::lang;
47using namespace ::com::sun::star::awt;
48using namespace ::com::sun::star::io;
49using namespace ::com::sun::star::container;
50using namespace ::com::sun::star::util;
51using namespace ::osl;
52using namespace ::comphelper;
53using namespace ::cppu;
54
55
56// OColumn
57OColumn::OColumn( const bool _bNameIsReadOnly )
60{
61
62 registerProperty( PROPERTY_NAME, PROPERTY_ID_NAME, _bNameIsReadOnly ? PropertyAttribute::READONLY : 0,
63 &m_sName, cppu::UnoType<decltype(m_sName)>::get() );
64}
65
66OColumn::~OColumn()
67{
68}
69
70// css::lang::XTypeProvider
71Sequence< Type > OColumn::getTypes()
72{
73 return ::comphelper::concatSequences(
74 OColumnBase::getTypes(),
75 getBaseTypes()
76 );
77}
78
79// css::uno::XInterface
81
82// css::lang::XServiceInfo
83OUString OColumn::getImplementationName( )
84{
85 return "com.sun.star.sdb.OColumn";
86}
87
88sal_Bool OColumn::supportsService( const OUString& _rServiceName )
89{
90 return cppu::supportsService(this, _rServiceName);
91}
92
93Sequence< OUString > OColumn::getSupportedServiceNames( )
94{
95 return { SERVICE_SDBCX_COLUMN };
96}
97
98// OComponentHelper
99void OColumn::disposing()
100{
101 OPropertyContainer::disposing();
102}
103
104// css::beans::XPropertySet
105Reference< XPropertySetInfo > OColumn::getPropertySetInfo()
106{
107 return createPropertySetInfo( getInfoHelper() ) ;
108}
109
110OUString SAL_CALL OColumn::getName( )
111{
112 return m_sName;
113}
114
115void SAL_CALL OColumn::setName( const OUString& _rName )
116{
117 m_sName = _rName;
118}
119
120void OColumn::registerProperty( const OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, void* _pPointerToMember, const Type& _rMemberType )
121{
122 ::comphelper::OPropertyContainer::registerProperty( _rName, _nHandle, _nAttributes, _pPointerToMember, _rMemberType );
123}
124
125void OColumn::registerMayBeVoidProperty( const OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, Any* _pPointerToMember, const Type& _rExpectedType )
126{
127 ::comphelper::OPropertyContainer::registerMayBeVoidProperty( _rName, _nHandle, _nAttributes, _pPointerToMember, _rExpectedType );
128}
129
130// OColumns
131
132OColumns::OColumns(::cppu::OWeakObject& _rParent,
133 ::osl::Mutex& _rMutex,
134 bool _bCaseSensitive,const std::vector< OUString> &_rVector,
135 IColumnFactory* _pColFactory,
137 bool _bAddColumn,
138 bool _bDropColumn,
139 bool _bUseHardRef)
140 : OColumns_BASE(_rParent,_bCaseSensitive,_rMutex,_rVector,_bUseHardRef)
141 ,m_pMediator(nullptr)
142 ,m_pColFactoryImpl(_pColFactory)
143 ,m_pRefreshColumns(_pRefresh)
144 ,m_bInitialized(false)
145 ,m_bAddColumn(_bAddColumn)
146 ,m_bDropColumn(_bDropColumn)
147{
148}
149
150OColumns::OColumns(::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex,
151 css::uno::Reference< css::container::XNameAccess > _xDrvColumns,
152 bool _bCaseSensitive,const std::vector< OUString> &_rVector,
153 IColumnFactory* _pColFactory,
155 bool _bAddColumn,
156 bool _bDropColumn,
157 bool _bUseHardRef)
158 : OColumns_BASE(_rParent,_bCaseSensitive,_rMutex,_rVector,_bUseHardRef)
159 ,m_pMediator(nullptr)
160 ,m_xDrvColumns(std::move(_xDrvColumns))
161 ,m_pColFactoryImpl(_pColFactory)
162 ,m_pRefreshColumns(_pRefresh)
163 ,m_bInitialized(false)
164 ,m_bAddColumn(_bAddColumn)
165 ,m_bDropColumn(_bDropColumn)
166{
167}
168
170{
171}
172
173// XServiceInfo
175{
176 return "com.sun.star.sdb.OColumns";
177}
178
179sal_Bool OColumns::supportsService( const OUString& _rServiceName )
180{
181 return cppu::supportsService(this, _rServiceName);
182}
183
185{
186 return { SERVICE_SDBCX_CONTAINER };
187}
188
189void OColumns::append( const OUString& _rName, OColumn* _pColumn )
190{
191 MutexGuard aGuard(m_rMutex);
192
193 OSL_ENSURE( _pColumn, "OColumns::append: invalid column!" );
194 OSL_ENSURE( !m_pElements->exists( _rName ),"OColumns::append: Column already exists");
195
196 _pColumn->m_sName = _rName;
197
198 // now really insert the column
199 insertElement( _rName, _pColumn );
200}
201
203{
204 MutexGuard aGuard(m_rMutex);
205 disposing();
206}
207
209{
210 MutexGuard aGuard(m_rMutex);
211 m_xDrvColumns = nullptr;
212 m_pMediator = nullptr;
213 m_pColFactoryImpl = nullptr;
215}
216
218{
221}
222
224{
225 OSL_ENSURE(m_pColFactoryImpl, "OColumns::createObject: no column factory!");
226
228 if ( m_pColFactoryImpl )
229 {
230 xRet = m_pColFactoryImpl->createColumn(_rName);
231 Reference<XChild> xChild(xRet,UNO_QUERY);
232 if ( xChild.is() )
233 xChild->setParent(static_cast<XChild*>(static_cast<TXChild*>(this)));
234 }
235
236 Reference<XPropertySet> xDest(xRet,UNO_QUERY);
237 if ( m_pMediator && xDest.is() )
238 m_pMediator->notifyElementCreated(_rName,xDest);
239
240 return xRet;
241}
242
243Reference< XPropertySet > OColumns::createDescriptor()
244{
245 if ( m_pColFactoryImpl )
246 {
247 Reference<XPropertySet> xRet = m_pColFactoryImpl->createColumnDescriptor();
248 Reference<XChild> xChild(xRet,UNO_QUERY);
249 if ( xChild.is() )
250 xChild->setParent(static_cast<XChild*>(static_cast<TXChild*>(this)));
251 return xRet;
252 }
253 else
254 return Reference< XPropertySet >();
255}
256
257Any SAL_CALL OColumns::queryInterface( const Type & rType )
258{
259 Any aRet;
260 if(m_xDrvColumns.is())
261 {
262 aRet = m_xDrvColumns->queryInterface(rType);
263 if ( aRet.hasValue() )
264 aRet = OColumns_BASE::queryInterface( rType);
265 if ( !aRet.hasValue() )
266 aRet = TXChild::queryInterface( rType);
267 return aRet;
268 }
269 else if(!m_pTable || !m_pTable->isNew())
270 {
272 return Any();
274 return Any();
275 }
276
277 aRet = OColumns_BASE::queryInterface( rType);
278 if ( !aRet.hasValue() )
279 aRet = TXChild::queryInterface( rType);
280 return aRet;
281}
282
283Sequence< Type > SAL_CALL OColumns::getTypes( )
284{
285 bool bAppendFound = false,bDropFound = false;
286
287 sal_Int32 nSize = 0;
288 Type aAppendType = cppu::UnoType<XAppend>::get();
289 Type aDropType = cppu::UnoType<XDrop>::get();
290 if(m_xDrvColumns.is())
291 {
292 Reference<XTypeProvider> xTypes(m_xDrvColumns,UNO_QUERY);
293 Sequence< Type > aTypes(xTypes->getTypes());
294
295 const Type* pBegin = aTypes.getConstArray();
296 const Type* pEnd = pBegin + aTypes.getLength();
297 for (;pBegin != pEnd ; ++pBegin)
298 {
299 if(aAppendType == *pBegin)
300 bAppendFound = true;
301 else if(aDropType == *pBegin)
302 bDropFound = true;
303 }
304 nSize = (bDropFound ? (bAppendFound ? 0 : 1) : (bAppendFound ? 1 : 2));
305 }
306 else
307 {
308 if (m_pTable && m_pTable->isNew())
309 nSize = 0;
310 else if (m_bDropColumn)
311 nSize = m_bAddColumn ? 0 : 1;
312 else
313 nSize = m_bAddColumn ? 1 : 2;
314 bDropFound = (m_pTable && m_pTable->isNew()) || m_bDropColumn;
315 bAppendFound = (m_pTable && m_pTable->isNew()) || m_bAddColumn;
316 }
317 Sequence< Type > aTypes(::comphelper::concatSequences(OColumns_BASE::getTypes(),TXChild::getTypes()));
318 Sequence< Type > aRet(aTypes.getLength() - nSize);
319
320 const Type* pBegin = aTypes.getConstArray();
321 const Type* pEnd = pBegin + aTypes.getLength();
322 for(sal_Int32 i=0;pBegin != pEnd ;++pBegin)
323 {
324 if(*pBegin != aAppendType && *pBegin != aDropType)
325 aRet.getArray()[i++] = *pBegin;
326 else if(bDropFound && *pBegin == aDropType)
327 aRet.getArray()[i++] = *pBegin;
328 else if(bAppendFound && *pBegin == aAppendType)
329 aRet.getArray()[i++] = *pBegin;
330 }
331 return aRet;
332}
333
334// XAppend
335sdbcx::ObjectType OColumns::appendObject( const OUString& _rForName, const Reference< XPropertySet >& descriptor )
336{
337 sdbcx::ObjectType xReturn;
338
339 Reference< XAppend > xAppend( m_xDrvColumns, UNO_QUERY );
340 if ( xAppend.is() )
341 {
342 xAppend->appendByDescriptor(descriptor);
343 xReturn = createObject( _rForName );
344 }
345 else if ( m_pTable && !m_pTable->isNew() )
346 {
347 if ( m_bAddColumn )
348 {
349 Reference< css::sdb::tools::XTableAlteration> xAlterService = m_pTable->getAlterService();
350 if ( xAlterService.is() )
351 {
352 xAlterService->addColumn(m_pTable,descriptor);
353 xReturn = createObject( _rForName );
354 }
355 else
356 xReturn = OColumns_BASE::appendObject( _rForName, descriptor );
357 }
358 else
359 ::dbtools::throwGenericSQLException( DBA_RES( RID_STR_NO_COLUMN_ADD ), static_cast<XChild*>(static_cast<TXChild*>(this)) );
360 }
361 else
362 xReturn = cloneDescriptor( descriptor );
363
364 if ( m_pColFactoryImpl )
365 m_pColFactoryImpl->columnAppended( descriptor );
366
368
369 return xReturn;
370}
371
372// XDrop
373void OColumns::dropObject(sal_Int32 _nPos, const OUString& _sElementName)
374{
375 Reference< XDrop > xDrop( m_xDrvColumns, UNO_QUERY );
376 if ( xDrop.is() )
377 {
378 xDrop->dropByName( _sElementName );
379 }
380 else if ( m_pTable && !m_pTable->isNew() )
381 {
382 if ( m_bDropColumn )
383 {
384 Reference< css::sdb::tools::XTableAlteration> xAlterService = m_pTable->getAlterService();
385 if ( xAlterService.is() )
386 xAlterService->dropColumn(m_pTable,_sElementName);
387 else
388 OColumns_BASE::dropObject(_nPos,_sElementName);
389 }
390 else
391 ::dbtools::throwGenericSQLException( DBA_RES( RID_STR_NO_COLUMN_DROP ), static_cast<XChild*>(static_cast<TXChild*>(this)) );
392 }
393
394 if ( m_pColFactoryImpl )
395 m_pColFactoryImpl->columnDropped(_sElementName);
396
398}
399
400Reference< XInterface > SAL_CALL OColumns::getParent( )
401{
402 ::osl::MutexGuard aGuard(m_rMutex);
403 return m_xParent;
404}
405
406void SAL_CALL OColumns::setParent( const Reference< XInterface >& _xParent )
407{
408 ::osl::MutexGuard aGuard(m_rMutex);
409 m_xParent = _xParent;
410}
411
412/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void registerProperty(const OUString &_rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, void *_pPointerToMember, const css::uno::Type &_rMemberType)
void registerMayBeVoidProperty(const OUString &_rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, css::uno::Any *_pPointerToMember, const css::uno::Type &_rExpectedType)
virtual sdbcx::ObjectType appendObject(const OUString &_rForName, const css::uno::Reference< css::beans::XPropertySet > &descriptor) override
virtual void dropObject(sal_Int32 _nPos, const OUString &_sElementName) override
css::uno::Reference< css::sdb::tools::XTableAlteration > const & getAlterService() const
void insertElement(const OUString &_sElementName, const ObjectType &_xElement)
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
::std::unique_ptr< IObjectCollection > m_pElements
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
ObjectType cloneDescriptor(const ObjectType &_descriptor)
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() SAL_OVERRIDE
css::uno::Type const & get()
virtual void columnAppended(const css::uno::Reference< css::beans::XPropertySet > &_rxSourceDescriptor)=0
notifies that a column, created from a column descriptor, has been appended
virtual css::uno::Reference< css::beans::XPropertySet > createColumnDescriptor()=0
creates a column descriptor object.
virtual rtl::Reference< OColumn > createColumn(const OUString &_rName) const =0
creates an OColumn object which should represent the column with a given name
virtual void columnDropped(const OUString &_sName)=0
notifies that a column with a given name has been dropped
virtual void registerProperty(const OUString &_rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, void *_pPointerToMember, const css::uno::Type &_rMemberType) override
Definition: column.cxx:120
virtual void SAL_CALL setParent(const css::uno::Reference< css::uno::XInterface > &Parent) override
Definition: column.cxx:406
OContainerMediator * m_pMediator
Definition: column.hxx:129
virtual void dropObject(sal_Int32 _nPos, const OUString &_sElementName) override
Definition: column.cxx:373
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent() override
Definition: column.cxx:400
IColumnFactory * m_pColFactoryImpl
Definition: column.hxx:134
void append(const OUString &rName, OColumn *)
Definition: column.cxx:189
virtual connectivity::sdbcx::ObjectType appendObject(const OUString &_rForName, const css::uno::Reference< css::beans::XPropertySet > &descriptor) override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: column.cxx:184
virtual connectivity::sdbcx::ObjectType createObject(const OUString &_rName) override
Definition: column.cxx:223
::connectivity::sdbcx::IRefreshableColumns * m_pRefreshColumns
Definition: column.hxx:135
virtual void disposing() override
Definition: column.cxx:208
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) override
Definition: column.cxx:257
OColumns(::cppu::OWeakObject &_rParent, ::osl::Mutex &_rMutex, bool _bCaseSensitive, const std::vector< OUString > &_rVector, IColumnFactory *_pColFactory, ::connectivity::sdbcx::IRefreshableColumns *_pRefresh, bool _bAddColumn=false, bool _bDropColumn=false, bool _bUseHardRef=true)
constructs an empty container without configuration location.
Definition: column.cxx:132
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: column.cxx:283
css::uno::WeakReference< css::uno::XInterface > m_xParent
Definition: column.hxx:133
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: column.cxx:179
virtual css::uno::Reference< css::beans::XPropertySet > createDescriptor() override
Definition: column.cxx:243
css::uno::Reference< css::container::XNameAccess > m_xDrvColumns
Definition: column.hxx:132
virtual ~OColumns() override
Definition: column.cxx:169
virtual OUString SAL_CALL getImplementationName() override
Definition: column.cxx:174
void clearColumns()
Definition: column.cxx:202
virtual void impl_refresh() override
Definition: column.cxx:217
void notifyElementCreated(const OUString &_sElementName, const css::uno::Reference< css::beans::XPropertySet > &_xElement)
#define DBA_RES(id)
OUString m_sName
std::mutex m_aMutex
Type
css::uno::Reference< css::beans::XPropertySet > ObjectType
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
::cppu::WeakComponentImplHelper< css::lang::XServiceInfo, css::container::XNamed > OColumnBase
Definition: column.hxx:44
void notifyDataSourceModified(const css::uno::Reference< css::uno::XInterface > &_rxObject)
int i
IMPLEMENT_FORWARD_XINTERFACE2(OStatement, OStatementBase, OStatement_IFACE)
#define PROPERTY_ID_NAME
constexpr OUStringLiteral SERVICE_SDBCX_CONTAINER
Definition: strings.hxx:171
constexpr OUStringLiteral SERVICE_SDBCX_COLUMN
Definition: strings.hxx:175
constexpr OUStringLiteral PROPERTY_NAME(u"Name")
unsigned char sal_Bool
const SvXMLTokenMapEntry aTypes[]
sal_Int32 _nPos