1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dbtools.cxx,v $
10 * $Revision: 1.74.46.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
34 #include "connectivity/CommonTools.hxx"
35 #include "diagnose_ex.h"
36 #include "TConnection.hxx"
37 #include "connectivity/ParameterCont.hxx"
39 /** === begin UNO includes === **/
40 #include <com/sun/star/awt/XWindow.hpp>
41 #include <com/sun/star/beans/PropertyAttribute.hpp>
42 #include <com/sun/star/container/XChild.hpp>
43 #include <com/sun/star/form/FormComponentType.hpp>
44 #include <com/sun/star/io/XInputStream.hpp>
45 #include <com/sun/star/lang/DisposedException.hpp>
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/sdb/BooleanComparisonMode.hpp>
48 #include <com/sun/star/sdb/CommandType.hpp>
49 #include <com/sun/star/sdb/ParametersRequest.hpp>
50 #include <com/sun/star/sdb/RowSetVetoException.hpp>
51 #include <com/sun/star/sdb/SQLContext.hpp>
52 #include <com/sun/star/sdb/XCompletedConnection.hpp>
53 #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
54 #include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
55 #include <com/sun/star/sdb/XParametersSupplier.hpp>
56 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
57 #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
58 #include <com/sun/star/sdbc/DataType.hpp>
59 #include <com/sun/star/sdbc/XConnection.hpp>
60 #include <com/sun/star/sdbc/XDataSource.hpp>
61 #include <com/sun/star/sdbc/XDriverManager.hpp>
62 #include <com/sun/star/sdbc/XParameters.hpp>
63 #include <com/sun/star/sdbc/XRow.hpp>
64 #include <com/sun/star/sdbc/XRowSet.hpp>
65 #include <com/sun/star/sdbc/XRowUpdate.hpp>
66 #include <com/sun/star/sdbcx/Privilege.hpp>
67 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
68 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
69 #include <com/sun/star/task/XInteractionHandler.hpp>
70 #include <com/sun/star/task/XInteractionRequest.hpp>
71 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
72 #include <com/sun/star/uno/XNamingService.hpp>
73 #include <com/sun/star/util/NumberFormat.hpp>
74 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
75 #include <com/sun/star/util/XNumberFormatTypes.hpp>
76 /** === end UNO includes === **/
78 #include <comphelper/extract.hxx>
79 #include <comphelper/interaction.hxx>
80 #include <comphelper/property.hxx>
81 #include <connectivity/conncleanup.hxx>
82 #include <connectivity/dbconversion.hxx>
83 #include <connectivity/dbexception.hxx>
84 #include <connectivity/dbtools.hxx>
85 #include <connectivity/statementcomposer.hxx>
86 #include <osl/diagnose.h>
87 #include <rtl/ustrbuf.hxx>
88 #include <tools/diagnose_ex.h>
90 #include "resource/common_res.hrc"
91 #include "resource/sharedresources.hxx"
92 #include "OSubComponent.hxx"
96 using namespace ::comphelper
;
97 using namespace ::com::sun::star::uno
;
98 using namespace ::com::sun::star::io
;
99 using namespace ::com::sun::star::awt
;
100 using namespace ::com::sun::star::ui::dialogs
;
101 using namespace ::com::sun::star::util
;
102 using namespace ::com::sun::star::lang
;
103 using namespace ::com::sun::star::beans
;
104 using namespace ::com::sun::star::container
;
105 using namespace ::com::sun::star::sdb
;
106 using namespace ::com::sun::star::sdbc
;
107 using namespace ::com::sun::star::sdbcx
;
108 using namespace ::com::sun::star::form
;
109 using namespace connectivity
;
111 //.........................................................................
114 //.........................................................................
116 using namespace ::com::sun::star::uno
;
117 using namespace ::com::sun::star::beans
;
118 using namespace ::com::sun::star::util
;
119 using namespace ::com::sun::star::task
;
120 using namespace ::com::sun::star::uno
;
121 using namespace ::com::sun::star::lang
;
122 using namespace ::com::sun::star::sdbc
;
123 using namespace ::com::sun::star::task
;
124 // using namespace cppu;
125 // using namespace osl;
127 //==============================================================================
128 //==============================================================================
131 typedef sal_Bool (SAL_CALL
XDatabaseMetaData::*FMetaDataSupport
)();
133 //==============================================================================
134 //==============================================================================
135 sal_Int32
getDefaultNumberFormat(const Reference
< XPropertySet
>& _xColumn
,
136 const Reference
< XNumberFormatTypes
>& _xTypes
,
137 const Locale
& _rLocale
)
139 OSL_ENSURE(_xTypes
.is() && _xColumn
.is(), "dbtools::getDefaultNumberFormat: invalid arg !");
140 if (!_xTypes
.is() || !_xColumn
.is())
141 return NumberFormat::UNDEFINED
;
143 sal_Int32 nDataType
= 0;
144 sal_Int32 nScale
= 0;
147 // determine the datatype of the column
148 _xColumn
->getPropertyValue(::rtl::OUString::createFromAscii("Type")) >>= nDataType
;
150 if (DataType::NUMERIC
== nDataType
|| DataType::DECIMAL
== nDataType
)
151 _xColumn
->getPropertyValue(::rtl::OUString::createFromAscii("Scale")) >>= nScale
;
155 return NumberFormat::UNDEFINED
;
157 return getDefaultNumberFormat(nDataType
,
159 ::cppu::any2bool(_xColumn
->getPropertyValue(::rtl::OUString::createFromAscii("IsCurrency"))),
164 //------------------------------------------------------------------
165 sal_Int32
getDefaultNumberFormat(sal_Int32 _nDataType
,
167 sal_Bool _bIsCurrency
,
168 const Reference
< XNumberFormatTypes
>& _xTypes
,
169 const Locale
& _rLocale
)
171 OSL_ENSURE(_xTypes
.is() , "dbtools::getDefaultNumberFormat: invalid arg !");
173 return NumberFormat::UNDEFINED
;
175 sal_Int32 nFormat
= 0;
176 sal_Int32 nNumberType
= _bIsCurrency
? NumberFormat::CURRENCY
: NumberFormat::NUMBER
;
180 case DataType::BOOLEAN
:
181 nFormat
= _xTypes
->getStandardFormat(NumberFormat::LOGICAL
, _rLocale
);
183 case DataType::TINYINT
:
184 case DataType::SMALLINT
:
185 case DataType::INTEGER
:
186 case DataType::BIGINT
:
187 case DataType::FLOAT
:
189 case DataType::DOUBLE
:
190 case DataType::NUMERIC
:
191 case DataType::DECIMAL
:
195 nFormat
= _xTypes
->getStandardFormat((sal_Int16
)nNumberType
, _rLocale
);
198 // generate a new format if necessary
199 Reference
< XNumberFormats
> xFormats(_xTypes
, UNO_QUERY
);
200 ::rtl::OUString sNewFormat
= xFormats
->generateFormat( 0L, _rLocale
, sal_False
, sal_False
, (sal_Int16
)_nScale
, sal_True
);
202 // and add it to the formatter if necessary
203 nFormat
= xFormats
->queryKey(sNewFormat
, _rLocale
, sal_False
);
204 if (nFormat
== (sal_Int32
)-1)
205 nFormat
= xFormats
->addNew(sNewFormat
, _rLocale
);
210 nFormat
= _xTypes
->getStandardFormat((sal_Int16
)nNumberType
, _rLocale
);
214 case DataType::VARCHAR
:
215 case DataType::LONGVARCHAR
:
216 nFormat
= _xTypes
->getStandardFormat(NumberFormat::TEXT
, _rLocale
);
219 nFormat
= _xTypes
->getStandardFormat(NumberFormat::DATE
, _rLocale
);
222 nFormat
= _xTypes
->getStandardFormat(NumberFormat::TIME
, _rLocale
);
224 case DataType::TIMESTAMP
:
225 nFormat
= _xTypes
->getStandardFormat(NumberFormat::DATETIME
, _rLocale
);
227 case DataType::BINARY
:
228 case DataType::VARBINARY
:
229 case DataType::LONGVARBINARY
:
230 case DataType::SQLNULL
:
231 case DataType::OTHER
:
232 case DataType::OBJECT
:
233 case DataType::DISTINCT
:
234 case DataType::STRUCT
:
235 case DataType::ARRAY
:
240 nFormat
= NumberFormat::UNDEFINED
;
245 //==============================================================================
246 //------------------------------------------------------------------------------
247 Reference
< XConnection
> findConnection(const Reference
< XInterface
>& xParent
)
249 Reference
< XConnection
> xConnection(xParent
, UNO_QUERY
);
250 if (!xConnection
.is())
252 Reference
< XChild
> xChild(xParent
, UNO_QUERY
);
254 xConnection
= findConnection(xChild
->getParent());
259 //------------------------------------------------------------------------------
260 Reference
< XDataSource
> getDataSource_allowException(
261 const ::rtl::OUString
& _rsTitleOrPath
,
262 const Reference
< XMultiServiceFactory
>& _rxFactory
)
264 OSL_ENSURE( _rsTitleOrPath
.getLength(), "getDataSource_allowException: invalid arg !" );
266 Reference
< XNameAccess
> xDatabaseContext(
267 _rxFactory
->createInstance(
268 ::rtl::OUString::createFromAscii( "com.sun.star.sdb.DatabaseContext" ) ),UNO_QUERY
);
269 OSL_ENSURE( xDatabaseContext
.is(), "getDataSource_allowException: could not obtain the database context!" );
271 return Reference
< XDataSource
>( xDatabaseContext
->getByName( _rsTitleOrPath
), UNO_QUERY
);
274 //------------------------------------------------------------------------------
275 Reference
< XDataSource
> getDataSource(
276 const ::rtl::OUString
& _rsTitleOrPath
,
277 const Reference
< XMultiServiceFactory
>& _rxFactory
)
279 Reference
< XDataSource
> xDS
;
282 xDS
= getDataSource_allowException( _rsTitleOrPath
, _rxFactory
);
291 //------------------------------------------------------------------------------
292 Reference
< XConnection
> getConnection_allowException(
293 const ::rtl::OUString
& _rsTitleOrPath
,
294 const ::rtl::OUString
& _rsUser
,
295 const ::rtl::OUString
& _rsPwd
,
296 const Reference
< XMultiServiceFactory
>& _rxFactory
)
298 Reference
< XDataSource
> xDataSource( getDataSource_allowException(_rsTitleOrPath
, _rxFactory
) );
299 Reference
<XConnection
> xConnection
;
300 if (xDataSource
.is())
302 // do it with interaction handler
303 if(!_rsUser
.getLength() || !_rsPwd
.getLength())
305 Reference
<XPropertySet
> xProp(xDataSource
,UNO_QUERY
);
306 ::rtl::OUString sPwd
, sUser
;
307 sal_Bool bPwdReq
= sal_False
;
310 xProp
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD
)) >>= sPwd
;
311 bPwdReq
= ::cppu::any2bool(xProp
->getPropertyValue(::rtl::OUString::createFromAscii("IsPasswordRequired")));
312 xProp
->getPropertyValue(::rtl::OUString::createFromAscii("User")) >>= sUser
;
316 OSL_ENSURE(sal_False
, "dbtools::getConnection: error while retrieving data source properties!");
318 if(bPwdReq
&& !sPwd
.getLength())
319 { // password required, but empty -> connect using an interaction handler
320 Reference
<XCompletedConnection
> xConnectionCompletion(xProp
, UNO_QUERY
);
321 if (xConnectionCompletion
.is())
322 { // instantiate the default SDB interaction handler
323 Reference
< XInteractionHandler
> xHandler(_rxFactory
->createInstance(::rtl::OUString::createFromAscii("com.sun.star.sdb.InteractionHandler")), UNO_QUERY
);
324 OSL_ENSURE(xHandler
.is(), "dbtools::getConnection service com.sun.star.sdb.InteractionHandler not available!");
327 xConnection
= xConnectionCompletion
->connectWithCompletion(xHandler
);
332 xConnection
= xDataSource
->getConnection(sUser
, sPwd
);
334 if(!xConnection
.is()) // try to get one if not already have one, just to make sure
335 xConnection
= xDataSource
->getConnection(_rsUser
, _rsPwd
);
340 //------------------------------------------------------------------------------
341 Reference
< XConnection
> getConnection_withFeedback(const ::rtl::OUString
& _rDataSourceName
,
342 const ::rtl::OUString
& _rUser
, const ::rtl::OUString
& _rPwd
, const Reference
< XMultiServiceFactory
>& _rxFactory
)
343 SAL_THROW ( (SQLException
) )
345 Reference
< XConnection
> xReturn
;
348 xReturn
= getConnection_allowException(_rDataSourceName
, _rUser
, _rPwd
, _rxFactory
);
357 OSL_ENSURE(sal_False
, "::dbtools::getConnection_withFeedback: unexpected (non-SQL) exception caught!");
362 //------------------------------------------------------------------------------
363 Reference
< XConnection
> getConnection(
364 const ::rtl::OUString
& _rsTitleOrPath
,
365 const ::rtl::OUString
& _rsUser
,
366 const ::rtl::OUString
& _rsPwd
,
367 const Reference
< XMultiServiceFactory
>& _rxFactory
)
369 Reference
< XConnection
> xReturn
;
372 xReturn
= getConnection_allowException(_rsTitleOrPath
, _rsUser
, _rsPwd
, _rxFactory
);
378 // TODO: if there were not dozens of places which rely on getConnection not throwing an exception ....
379 // I would change this ...
384 //------------------------------------------------------------------------------
385 Reference
< XConnection
> getConnection(const Reference
< XRowSet
>& _rxRowSet
) throw (RuntimeException
)
387 Reference
< XConnection
> xReturn
;
388 Reference
< XPropertySet
> xRowSetProps(_rxRowSet
, UNO_QUERY
);
389 if (xRowSetProps
.is())
390 xRowSetProps
->getPropertyValue(::rtl::OUString::createFromAscii("ActiveConnection")) >>= xReturn
;
394 //------------------------------------------------------------------------------
395 // helper function which allows to implement both the connectRowset and the ensureRowSetConnection semantics
396 // if connectRowset (which is deprecated) is removed, this function and one of its parameters are
397 // not needed anymore, the whole implementation can be moved into ensureRowSetConnection then)
398 SharedConnection
lcl_connectRowSet(const Reference
< XRowSet
>& _rxRowSet
, const Reference
< XMultiServiceFactory
>& _rxFactory
,
399 bool _bSetAsActiveConnection
, bool _bAttachAutoDisposer
)
400 SAL_THROW ( ( SQLException
, WrappedTargetException
, RuntimeException
) )
402 SharedConnection xConnection
;
406 Reference
< XPropertySet
> xRowSetProps(_rxRowSet
, UNO_QUERY
);
407 if ( !xRowSetProps
.is() )
410 // 1. already connected?
411 Reference
< XConnection
> xExistingConn(
412 xRowSetProps
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ActiveConnection" ) ) ),
415 if ( xExistingConn
.is()
416 // 2. embedded in a database?
417 || isEmbeddedInDatabase( _rxRowSet
, xExistingConn
)
418 // 3. is there a connection in the parent hierarchy?
419 || ( xExistingConn
= findConnection( _rxRowSet
) ).is()
422 if ( _bSetAsActiveConnection
)
424 xRowSetProps
->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ActiveConnection" ) ), makeAny( xExistingConn
) );
425 // no auto disposer needed, since we did not create the connection
428 xConnection
.reset( xExistingConn
, SharedConnection::NoTakeOwnership
);
432 // build a connection with it's current settings (4. data source name, or 5. URL)
434 const ::rtl::OUString sUserProp
= ::rtl::OUString::createFromAscii("User");
435 ::rtl::OUString sDataSourceName
;
436 xRowSetProps
->getPropertyValue(::rtl::OUString::createFromAscii("DataSourceName")) >>= sDataSourceName
;
437 ::rtl::OUString sURL
;
438 xRowSetProps
->getPropertyValue(::rtl::OUString::createFromAscii("URL")) >>= sURL
;
440 Reference
< XConnection
> xPureConnection
;
441 if (sDataSourceName
.getLength())
442 { // the row set's data source property is set
443 // -> try to connect, get user and pwd setting for that
444 ::rtl::OUString sUser
, sPwd
;
446 if (hasProperty(sUserProp
, xRowSetProps
))
447 xRowSetProps
->getPropertyValue(sUserProp
) >>= sUser
;
448 if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD
), xRowSetProps
))
449 xRowSetProps
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD
)) >>= sPwd
;
451 xPureConnection
= getConnection_allowException( sDataSourceName
, sUser
, sPwd
, _rxFactory
);
453 else if (sURL
.getLength())
454 { // the row set has no data source, but a connection url set
455 // -> try to connection with that url
456 Reference
< XDriverManager
> xDriverManager(
457 _rxFactory
->createInstance( ::rtl::OUString::createFromAscii("com.sun.star.sdbc.ConnectionPool")), UNO_QUERY
);
458 if (xDriverManager
.is())
460 ::rtl::OUString sUser
, sPwd
;
461 if (hasProperty(sUserProp
, xRowSetProps
))
462 xRowSetProps
->getPropertyValue(sUserProp
) >>= sUser
;
463 if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD
), xRowSetProps
))
464 xRowSetProps
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD
)) >>= sPwd
;
465 if (sUser
.getLength())
466 { // use user and pwd together with the url
467 Sequence
< PropertyValue
> aInfo(2);
468 aInfo
.getArray()[0].Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("user"));
469 aInfo
.getArray()[0].Value
<<= sUser
;
470 aInfo
.getArray()[1].Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("password"));
471 aInfo
.getArray()[1].Value
<<= sPwd
;
472 xPureConnection
= xDriverManager
->getConnectionWithInfo( sURL
, aInfo
);
476 xPureConnection
= xDriverManager
->getConnection( sURL
);
481 _bAttachAutoDisposer
? SharedConnection::NoTakeOwnership
: SharedConnection::TakeOwnership
482 /* take ownership if and only if we're *not* going to auto-dispose the connection */
485 // now if we created a connection, forward it to the row set
486 if ( xConnection
.is() && _bSetAsActiveConnection
)
490 if ( _bAttachAutoDisposer
)
492 OAutoConnectionDisposer
* pAutoDispose
= new OAutoConnectionDisposer( _rxRowSet
, xConnection
);
493 Reference
< XPropertyChangeListener
> xEnsureDelete(pAutoDispose
);
496 xRowSetProps
->setPropertyValue(
497 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ActiveConnection" ) ),
498 makeAny( xConnection
.getTyped() )
503 OSL_ENSURE(0,"EXception when we set the new active connection!");
512 //------------------------------------------------------------------------------
513 Reference
< XConnection
> connectRowset(const Reference
< XRowSet
>& _rxRowSet
, const Reference
< XMultiServiceFactory
>& _rxFactory
,
514 sal_Bool _bSetAsActiveConnection
) SAL_THROW ( ( SQLException
, WrappedTargetException
, RuntimeException
) )
516 SharedConnection xConnection
= lcl_connectRowSet( _rxRowSet
, _rxFactory
, _bSetAsActiveConnection
, true );
517 return xConnection
.getTyped();
520 //------------------------------------------------------------------------------
521 SharedConnection
ensureRowSetConnection(const Reference
< XRowSet
>& _rxRowSet
, const Reference
< XMultiServiceFactory
>& _rxFactory
,
522 bool _bUseAutoConnectionDisposer
) SAL_THROW ( ( SQLException
, WrappedTargetException
, RuntimeException
) )
524 return lcl_connectRowSet( _rxRowSet
, _rxFactory
, true, _bUseAutoConnectionDisposer
);
527 //------------------------------------------------------------------------------
528 Reference
< XNameAccess
> getTableFields(const Reference
< XConnection
>& _rxConn
,const ::rtl::OUString
& _rName
)
530 Reference
< XComponent
> xDummy
;
531 return getFieldsByCommandDescriptor( _rxConn
, CommandType::TABLE
, _rName
, xDummy
);
534 //------------------------------------------------------------------------------
537 enum FieldLookupState
539 HANDLE_TABLE
, HANDLE_QUERY
, HANDLE_SQL
, RETRIEVE_OBJECT
, RETRIEVE_COLUMNS
, DONE
, FAILED
543 //------------------------------------------------------------------------------
544 Reference
< XNameAccess
> getFieldsByCommandDescriptor( const Reference
< XConnection
>& _rxConnection
,
545 const sal_Int32 _nCommandType
, const ::rtl::OUString
& _rCommand
,
546 Reference
< XComponent
>& _rxKeepFieldsAlive
, SQLExceptionInfo
* _pErrorInfo
) SAL_THROW( ( ) )
548 OSL_PRECOND( _rxConnection
.is(), "::dbtools::getFieldsByCommandDescriptor: invalid connection!" );
549 OSL_PRECOND( ( CommandType::TABLE
== _nCommandType
) || ( CommandType::QUERY
== _nCommandType
) || ( CommandType::COMMAND
== _nCommandType
),
550 "::dbtools::getFieldsByCommandDescriptor: invalid command type!" );
551 OSL_PRECOND( _rCommand
.getLength(), "::dbtools::getFieldsByCommandDescriptor: invalid command (empty)!" );
553 Reference
< XNameAccess
> xFields
;
557 *_pErrorInfo
= SQLExceptionInfo();
558 // reset the ownership holder
559 _rxKeepFieldsAlive
.clear();
564 // some kind of state machine to ease the sharing of code
565 FieldLookupState eState
= FAILED
;
566 switch ( _nCommandType
)
568 case CommandType::TABLE
:
569 eState
= HANDLE_TABLE
;
571 case CommandType::QUERY
:
572 eState
= HANDLE_QUERY
;
574 case CommandType::COMMAND
:
579 // needed in various states:
580 Reference
< XNameAccess
> xObjectCollection
;
581 Reference
< XColumnsSupplier
> xSupplyColumns
;
584 while ( ( DONE
!= eState
) && ( FAILED
!= eState
) )
590 // initial state for handling the tables
592 // get the table objects
593 Reference
< XTablesSupplier
> xSupplyTables( _rxConnection
, UNO_QUERY
);
594 if ( xSupplyTables
.is() )
595 xObjectCollection
= xSupplyTables
->getTables();
596 // if something went wrong 'til here, then this will be handled in the next state
598 // next state: get the object
599 eState
= RETRIEVE_OBJECT
;
605 // initial state for handling the tables
607 // get the table objects
608 Reference
< XQueriesSupplier
> xSupplyQueries( _rxConnection
, UNO_QUERY
);
609 if ( xSupplyQueries
.is() )
610 xObjectCollection
= xSupplyQueries
->getQueries();
611 // if something went wrong 'til here, then this will be handled in the next state
613 // next state: get the object
614 eState
= RETRIEVE_OBJECT
;
618 case RETRIEVE_OBJECT
:
619 // here we should have an object (aka query or table) collection, and are going
620 // to retrieve the desired object
622 // next state: default to FAILED
625 OSL_ENSURE( xObjectCollection
.is(), "::dbtools::getFieldsByCommandDescriptor: invalid connection (no sdb.Connection, or no Tables-/QueriesSupplier)!");
626 if ( xObjectCollection
.is() )
628 if ( xObjectCollection
.is() && xObjectCollection
->hasByName( _rCommand
) )
630 xObjectCollection
->getByName( _rCommand
) >>= xSupplyColumns
;
631 // (xSupplyColumns being NULL will be handled in the next state)
633 // next: go for the columns
634 eState
= RETRIEVE_COLUMNS
;
639 case RETRIEVE_COLUMNS
:
640 OSL_ENSURE( xSupplyColumns
.is(), "::dbtools::getFieldsByCommandDescriptor: could not retrieve the columns supplier!" );
642 // next state: default to FAILED
645 if ( xSupplyColumns
.is() )
647 xFields
= xSupplyColumns
->getColumns();
655 ::rtl::OUString
sStatementToExecute( _rCommand
);
657 // well, the main problem here is to handle statements which contain a parameter
658 // If we would simply execute a parametrized statement, then this will fail because
659 // we cannot supply any parameter values.
660 // Thus, we try to analyze the statement, and to append a WHERE 0=1 filter criterion
661 // This should cause every driver to not really execute the statement, but to return
662 // an empty result set with the proper structure. We then can use this result set
663 // to retrieve the columns.
667 Reference
< XMultiServiceFactory
> xComposerFac( _rxConnection
, UNO_QUERY
);
669 if ( xComposerFac
.is() )
671 Reference
< XSingleSelectQueryComposer
> xComposer(xComposerFac
->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.SingleSelectQueryComposer"))),UNO_QUERY
);
672 if ( xComposer
.is() )
674 xComposer
->setQuery( sStatementToExecute
);
676 // Now set the filter to a dummy restriction which will result in an empty
678 xComposer
->setFilter( ::rtl::OUString::createFromAscii( "0=1" ) );
679 sStatementToExecute
= xComposer
->getQuery( );
683 catch( const Exception
& )
685 // silent this error, this was just a try. If we're here, we did not change sStatementToExecute,
686 // so it will still be _rCommand, which then will be executed without being touched
690 Reference
< XPreparedStatement
> xStatement
= _rxConnection
->prepareStatement( sStatementToExecute
);
691 // transfer ownership of this temporary object to the caller
692 _rxKeepFieldsAlive
= _rxKeepFieldsAlive
.query( xStatement
);
694 // set the "MaxRows" to 0. This is just in case our attempt to append a 0=1 filter
695 // failed - in this case, the MaxRows restriction should at least ensure that there
696 // is no data returned (which would be potentially expensive)
697 Reference
< XPropertySet
> xStatementProps( xStatement
,UNO_QUERY
);
700 if ( xStatementProps
.is() )
701 xStatementProps
->setPropertyValue(
702 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MaxRows" ) ),
703 makeAny( sal_Int32( 0 ) )
706 catch( const Exception
& )
708 OSL_ENSURE( sal_False
, "::dbtools::getFieldsByCommandDescriptor: could not set the MaxRows!" );
709 // oh damn. Not much of a chance to recover, we will no retrieve the complete
710 // full blown result set
713 xSupplyColumns
= xSupplyColumns
.query( xStatement
->executeQuery() );
714 // this should have given us a result set which does not contain any data, but
715 // the structural information we need
717 // so the next state is to get the columns
718 eState
= RETRIEVE_COLUMNS
;
723 OSL_ENSURE( sal_False
, "::dbtools::getFieldsByCommandDescriptor: oops! unhandled state here!" );
728 catch( const SQLContext
& e
) { if ( _pErrorInfo
) *_pErrorInfo
= SQLExceptionInfo( e
); }
729 catch( const SQLWarning
& e
) { if ( _pErrorInfo
) *_pErrorInfo
= SQLExceptionInfo( e
); }
730 catch( const SQLException
& e
) { if ( _pErrorInfo
) *_pErrorInfo
= SQLExceptionInfo( e
); }
731 catch( const Exception
& )
733 OSL_ENSURE( sal_False
, "::dbtools::getFieldsByCommandDescriptor: caught an exception while retrieving the fields!" );
739 //------------------------------------------------------------------------------
740 Sequence
< ::rtl::OUString
> getFieldNamesByCommandDescriptor( const Reference
< XConnection
>& _rxConnection
,
741 const sal_Int32 _nCommandType
, const ::rtl::OUString
& _rCommand
,
742 SQLExceptionInfo
* _pErrorInfo
) SAL_THROW( ( ) )
744 // get the container for the fields
745 Reference
< XComponent
> xKeepFieldsAlive
;
746 Reference
< XNameAccess
> xFieldContainer
= getFieldsByCommandDescriptor( _rxConnection
, _nCommandType
, _rCommand
, xKeepFieldsAlive
, _pErrorInfo
);
748 // get the names of the fields
749 Sequence
< ::rtl::OUString
> aNames
;
750 if ( xFieldContainer
.is() )
751 aNames
= xFieldContainer
->getElementNames();
753 // clean up any temporary objects which have been created
754 disposeComponent( xKeepFieldsAlive
);
760 //------------------------------------------------------------------------------
761 SQLContext
prependContextInfo(const SQLException
& _rException
, const Reference
< XInterface
>& _rxContext
, const ::rtl::OUString
& _rContextDescription
, const ::rtl::OUString
& _rContextDetails
)
763 return SQLContext( _rContextDescription
, _rxContext
, ::rtl::OUString(), 0, makeAny( _rException
), _rContextDetails
);
765 //------------------------------------------------------------------------------
766 SQLException
prependErrorInfo( const SQLException
& _rChainedException
, const Reference
< XInterface
>& _rxContext
,
767 const ::rtl::OUString
& _rAdditionalError
, const StandardSQLState _eSQLState
, const sal_Int32 _nErrorCode
)
769 return SQLException( _rAdditionalError
, _rxContext
,
770 _eSQLState
== SQL_ERROR_UNSPECIFIED
? ::rtl::OUString() : getStandardSQLState( _eSQLState
),
771 _nErrorCode
, makeAny( _rChainedException
) );
774 //--------------------------------------------------------------------------
777 struct NameComponentSupport
779 const bool bCatalogs
;
782 NameComponentSupport( )
788 NameComponentSupport( const bool _bCatalogs
, const bool _bSchemas
)
789 :bCatalogs( _bCatalogs
)
790 ,bSchemas( _bSchemas
)
795 NameComponentSupport
lcl_getNameComponentSupport( const Reference
< XDatabaseMetaData
>& _rxMetaData
, EComposeRule _eComposeRule
)
797 OSL_PRECOND( _rxMetaData
.is(), "lcl_getNameComponentSupport: invalid meta data!" );
799 FMetaDataSupport pCatalogCall
= &XDatabaseMetaData::supportsCatalogsInDataManipulation
;
800 FMetaDataSupport pSchemaCall
= &XDatabaseMetaData::supportsSchemasInDataManipulation
;
801 bool bIgnoreMetaData
= false;
803 switch ( _eComposeRule
)
805 case eInTableDefinitions
:
806 pCatalogCall
= &XDatabaseMetaData::supportsCatalogsInTableDefinitions
;
807 pSchemaCall
= &XDatabaseMetaData::supportsSchemasInTableDefinitions
;
809 case eInIndexDefinitions
:
810 pCatalogCall
= &XDatabaseMetaData::supportsCatalogsInIndexDefinitions
;
811 pSchemaCall
= &XDatabaseMetaData::supportsSchemasInIndexDefinitions
;
813 case eInProcedureCalls
:
814 pCatalogCall
= &XDatabaseMetaData::supportsCatalogsInProcedureCalls
;
815 pSchemaCall
= &XDatabaseMetaData::supportsSchemasInProcedureCalls
;
817 case eInPrivilegeDefinitions
:
818 pCatalogCall
= &XDatabaseMetaData::supportsCatalogsInPrivilegeDefinitions
;
819 pSchemaCall
= &XDatabaseMetaData::supportsSchemasInPrivilegeDefinitions
;
822 bIgnoreMetaData
= true;
824 case eInDataManipulation
:
825 // already properly set above
828 return NameComponentSupport(
829 bIgnoreMetaData
? true : (_rxMetaData
.get()->*pCatalogCall
)(),
830 bIgnoreMetaData
? true : (_rxMetaData
.get()->*pSchemaCall
)()
835 //--------------------------------------------------------------------------
836 static ::rtl::OUString
impl_doComposeTableName( const Reference
< XDatabaseMetaData
>& _rxMetaData
,
837 const ::rtl::OUString
& _rCatalog
, const ::rtl::OUString
& _rSchema
, const ::rtl::OUString
& _rName
,
838 sal_Bool _bQuote
, EComposeRule _eComposeRule
)
840 OSL_ENSURE(_rxMetaData
.is(), "impl_doComposeTableName : invalid meta data !");
841 if ( !_rxMetaData
.is() )
842 return ::rtl::OUString();
843 OSL_ENSURE(_rName
.getLength(), "impl_doComposeTableName : at least the name should be non-empty !");
845 const ::rtl::OUString sQuoteString
= _rxMetaData
->getIdentifierQuoteString();
846 const NameComponentSupport
aNameComps( lcl_getNameComponentSupport( _rxMetaData
, _eComposeRule
) );
848 ::rtl::OUStringBuffer aComposedName
;
850 ::rtl::OUString sCatalogSep
;
851 sal_Bool bCatlogAtStart
= sal_True
;
852 if ( _rCatalog
.getLength() && aNameComps
.bCatalogs
)
854 sCatalogSep
= _rxMetaData
->getCatalogSeparator();
855 bCatlogAtStart
= _rxMetaData
->isCatalogAtStart();
857 if ( bCatlogAtStart
&& sCatalogSep
.getLength())
859 aComposedName
.append( _bQuote
? quoteName( sQuoteString
, _rCatalog
) : _rCatalog
);
860 aComposedName
.append( sCatalogSep
);
864 if ( _rSchema
.getLength() && aNameComps
.bSchemas
)
866 aComposedName
.append( _bQuote
? quoteName( sQuoteString
, _rSchema
) : _rSchema
);
867 aComposedName
.appendAscii( "." );
870 aComposedName
.append( _bQuote
? quoteName( sQuoteString
, _rName
) : _rName
);
872 if ( _rCatalog
.getLength()
874 && sCatalogSep
.getLength()
875 && aNameComps
.bCatalogs
878 aComposedName
.append( sCatalogSep
);
879 aComposedName
.append( _bQuote
? quoteName( sQuoteString
, _rCatalog
) : _rCatalog
);
882 return aComposedName
.makeStringAndClear();
885 //------------------------------------------------------------------------------
886 ::rtl::OUString
quoteTableName(const Reference
< XDatabaseMetaData
>& _rxMeta
887 , const ::rtl::OUString
& _rName
888 , EComposeRule _eComposeRule
)
890 ::rtl::OUString sCatalog
, sSchema
, sTable
;
891 qualifiedNameComponents(_rxMeta
,_rName
,sCatalog
,sSchema
,sTable
,_eComposeRule
);
892 return impl_doComposeTableName( _rxMeta
, sCatalog
, sSchema
, sTable
, sal_True
, _eComposeRule
);
895 //------------------------------------------------------------------------------
896 void qualifiedNameComponents(const Reference
< XDatabaseMetaData
>& _rxConnMetaData
, const ::rtl::OUString
& _rQualifiedName
, ::rtl::OUString
& _rCatalog
, ::rtl::OUString
& _rSchema
, ::rtl::OUString
& _rName
,EComposeRule _eComposeRule
)
898 OSL_ENSURE(_rxConnMetaData
.is(), "QualifiedNameComponents : invalid meta data!");
900 NameComponentSupport
aNameComps( lcl_getNameComponentSupport( _rxConnMetaData
, _eComposeRule
) );
902 ::rtl::OUString sSeparator
= _rxConnMetaData
->getCatalogSeparator();
904 ::rtl::OUString
sName(_rQualifiedName
);
905 // do we have catalogs ?
906 if ( aNameComps
.bCatalogs
)
908 if (_rxConnMetaData
->isCatalogAtStart())
910 // search for the catalog name at the beginning
911 sal_Int32 nIndex
= sName
.indexOf(sSeparator
);
914 _rCatalog
= sName
.copy(0, nIndex
);
915 sName
= sName
.copy(nIndex
+ 1);
920 // Katalogname am Ende
921 sal_Int32 nIndex
= sName
.lastIndexOf(sSeparator
);
924 _rCatalog
= sName
.copy(nIndex
+ 1);
925 sName
= sName
.copy(0, nIndex
);
930 if ( aNameComps
.bSchemas
)
932 sal_Int32 nIndex
= sName
.indexOf((sal_Unicode
)'.');
933 // OSL_ENSURE(-1 != nIndex, "QualifiedNameComponents : no schema separator!");
935 _rSchema
= sName
.copy(0, nIndex
);
936 sName
= sName
.copy(nIndex
+ 1);
942 //------------------------------------------------------------------------------
943 Reference
< XNumberFormatsSupplier
> getNumberFormats(
944 const Reference
< XConnection
>& _rxConn
,
945 sal_Bool _bAlloweDefault
,
946 const Reference
< XMultiServiceFactory
>& _rxFactory
)
948 // ask the parent of the connection (should be an DatabaseAccess)
949 Reference
< XNumberFormatsSupplier
> xReturn
;
950 Reference
< XChild
> xConnAsChild(_rxConn
, UNO_QUERY
);
951 ::rtl::OUString sPropFormatsSupplier
= ::rtl::OUString::createFromAscii("NumberFormatsSupplier");
952 if (xConnAsChild
.is())
954 Reference
< XPropertySet
> xConnParentProps(xConnAsChild
->getParent(), UNO_QUERY
);
955 if (xConnParentProps
.is() && hasProperty(sPropFormatsSupplier
, xConnParentProps
))
956 xConnParentProps
->getPropertyValue(sPropFormatsSupplier
) >>= xReturn
;
958 else if(_bAlloweDefault
&& _rxFactory
.is())
960 xReturn
= Reference
< XNumberFormatsSupplier
>(_rxFactory
->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatsSupplier")),UNO_QUERY
);
965 //==============================================================================
966 //------------------------------------------------------------------------------
967 void TransferFormComponentProperties(
968 const Reference
< XPropertySet
>& xOldProps
,
969 const Reference
< XPropertySet
>& xNewProps
,
970 const Locale
& _rLocale
)
974 OSL_ENSURE( xOldProps
.is() && xNewProps
.is(), "TransferFormComponentProperties: invalid source/dest!" );
975 if ( !xOldProps
.is() || !xNewProps
.is() )
978 // kopieren wir erst mal alle Props, die in Quelle und Ziel vorhanden sind und identische Beschreibungen haben
979 Reference
< XPropertySetInfo
> xOldInfo( xOldProps
->getPropertySetInfo());
980 Reference
< XPropertySetInfo
> xNewInfo( xNewProps
->getPropertySetInfo());
982 Sequence
< Property
> aOldProperties
= xOldInfo
->getProperties();
983 Sequence
< Property
> aNewProperties
= xNewInfo
->getProperties();
984 int nNewLen
= aNewProperties
.getLength();
986 Property
* pOldProps
= aOldProperties
.getArray();
987 Property
* pNewProps
= aNewProperties
.getArray();
989 ::rtl::OUString
sPropDefaultControl(::rtl::OUString::createFromAscii("DefaultControl"));
990 ::rtl::OUString
sPropLabelControl(::rtl::OUString::createFromAscii("LabelControl"));
991 ::rtl::OUString
sPropFormatsSupplier(::rtl::OUString::createFromAscii("FormatsSupplier"));
992 ::rtl::OUString
sPropCurrencySymbol(::rtl::OUString::createFromAscii("CurrencySymbol"));
993 ::rtl::OUString
sPropDecimals(::rtl::OUString::createFromAscii("Decimals"));
994 ::rtl::OUString
sPropEffectiveMin(::rtl::OUString::createFromAscii("EffectiveMin"));
995 ::rtl::OUString
sPropEffectiveMax(::rtl::OUString::createFromAscii("EffectiveMax"));
996 ::rtl::OUString
sPropEffectiveDefault(::rtl::OUString::createFromAscii("EffectiveDefault"));
997 ::rtl::OUString
sPropDefaultText(::rtl::OUString::createFromAscii("DefaultText"));
998 ::rtl::OUString
sPropDefaultDate(::rtl::OUString::createFromAscii("DefaultDate"));
999 ::rtl::OUString
sPropDefaultTime(::rtl::OUString::createFromAscii("DefaultTime"));
1000 ::rtl::OUString
sPropValueMin(::rtl::OUString::createFromAscii("ValueMin"));
1001 ::rtl::OUString
sPropValueMax(::rtl::OUString::createFromAscii("ValueMax"));
1002 ::rtl::OUString
sPropDecimalAccuracy(::rtl::OUString::createFromAscii("DecimalAccuracy"));
1003 ::rtl::OUString
sPropClassId(::rtl::OUString::createFromAscii("ClassId"));
1004 ::rtl::OUString
sFormattedServiceName( ::rtl::OUString::createFromAscii( "com.sun.star.form.component.FormattedField" ) );
1006 for (sal_Int16 i
=0; i
<aOldProperties
.getLength(); ++i
)
1008 if ( (!pOldProps
[i
].Name
.equals(sPropDefaultControl
))
1009 && (!pOldProps
[i
].Name
.equals(sPropLabelControl
))
1013 Property
* pResult
= ::std::lower_bound(pNewProps
, pNewProps
+ nNewLen
,pOldProps
[i
].Name
, ::comphelper::PropertyStringLessFunctor());
1015 && ( pResult
!= pNewProps
+ nNewLen
&& pResult
->Name
== pOldProps
[i
].Name
)
1016 && ( (pResult
->Attributes
& PropertyAttribute::READONLY
) == 0 )
1017 && ( pResult
->Type
.equals(pOldProps
[i
].Type
)) )
1018 { // Attribute stimmen ueberein und Property ist nicht read-only
1021 xNewProps
->setPropertyValue(pResult
->Name
, xOldProps
->getPropertyValue(pResult
->Name
));
1023 catch(IllegalArgumentException
& e
)
1027 ::rtl::OUString sMessage
= ::rtl::OUString::createFromAscii("TransferFormComponentProperties : could not transfer the value for property \"");
1028 sMessage
+= pResult
->Name
;
1029 sMessage
+= ::rtl::OUString::createFromAscii("\"");;
1030 OSL_ENSURE(sal_False
, ::rtl::OUStringToOString(sMessage
, RTL_TEXTENCODING_ASCII_US
));
1038 // fuer formatierte Felder (entweder alt oder neu) haben wir ein paar Sonderbehandlungen
1039 Reference
< XServiceInfo
> xSI( xOldProps
, UNO_QUERY
);
1040 sal_Bool bOldIsFormatted
= xSI
.is() && xSI
->supportsService( sFormattedServiceName
);
1041 xSI
= Reference
< XServiceInfo
>( xNewProps
, UNO_QUERY
);
1042 sal_Bool bNewIsFormatted
= xSI
.is() && xSI
->supportsService( sFormattedServiceName
);
1044 if (!bOldIsFormatted
&& !bNewIsFormatted
)
1045 return; // nothing to do
1047 if (bOldIsFormatted
&& bNewIsFormatted
)
1048 // nein, wenn beide formatierte Felder sind, dann machen wir keinerlei Konvertierungen
1049 // Das geht zu weit ;)
1052 if (bOldIsFormatted
)
1054 // aus dem eingestellten Format ein paar Properties rausziehen und zum neuen Set durchschleifen
1055 Any
aFormatKey( xOldProps
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY
)) );
1056 if (aFormatKey
.hasValue())
1058 Reference
< XNumberFormatsSupplier
> xSupplier
;
1059 xOldProps
->getPropertyValue(sPropFormatsSupplier
) >>= xSupplier
;
1062 Reference
< XNumberFormats
> xFormats(xSupplier
->getNumberFormats());
1063 Reference
< XPropertySet
> xFormat(xFormats
->getByKey(getINT32(aFormatKey
)));
1064 if (hasProperty(sPropCurrencySymbol
, xFormat
))
1066 Any
aVal( xFormat
->getPropertyValue(sPropCurrencySymbol
) );
1067 if (aVal
.hasValue() && hasProperty(sPropCurrencySymbol
, xNewProps
))
1068 // (wenn die Quelle das nicht gesetzt hat, dann auch nicht kopieren, um den
1069 // Default-Wert nicht zu ueberschreiben
1070 xNewProps
->setPropertyValue(sPropCurrencySymbol
, aVal
);
1072 if (hasProperty(sPropDecimals
, xFormat
) && hasProperty(sPropDecimals
, xNewProps
))
1073 xNewProps
->setPropertyValue(sPropDecimals
, xFormat
->getPropertyValue(sPropDecimals
));
1077 // eine eventuelle-Min-Max-Konvertierung
1078 Any
aEffectiveMin( xOldProps
->getPropertyValue(sPropEffectiveMin
) );
1079 if (aEffectiveMin
.hasValue())
1080 { // im Gegensatz zu ValueMin kann EffectiveMin void sein
1081 if (hasProperty(sPropValueMin
, xNewProps
))
1083 OSL_ENSURE(aEffectiveMin
.getValueType().getTypeClass() == TypeClass_DOUBLE
,
1084 "TransferFormComponentProperties : invalid property type !");
1085 xNewProps
->setPropertyValue(sPropValueMin
, aEffectiveMin
);
1088 Any
aEffectiveMax( xOldProps
->getPropertyValue(sPropEffectiveMax
) );
1089 if (aEffectiveMax
.hasValue())
1091 if (hasProperty(sPropValueMax
, xNewProps
))
1093 OSL_ENSURE(aEffectiveMax
.getValueType().getTypeClass() == TypeClass_DOUBLE
,
1094 "TransferFormComponentProperties : invalid property type !");
1095 xNewProps
->setPropertyValue(sPropValueMax
, aEffectiveMax
);
1099 // dann koennen wir noch Default-Werte konvertieren und uebernehmen
1100 Any
aEffectiveDefault( xOldProps
->getPropertyValue(sPropEffectiveDefault
) );
1101 if (aEffectiveDefault
.hasValue())
1103 sal_Bool bIsString
= aEffectiveDefault
.getValueType().getTypeClass() == TypeClass_STRING
;
1104 OSL_ENSURE(bIsString
|| aEffectiveDefault
.getValueType().getTypeClass() == TypeClass_DOUBLE
,
1105 "TransferFormComponentProperties : invalid property type !");
1106 // die Effective-Properties sollten immer void oder string oder double sein ....
1108 if (hasProperty(sPropDefaultDate
, xNewProps
) && !bIsString
)
1109 { // (einen ::rtl::OUString in ein Datum zu konvertieren muss nicht immer klappen, denn das ganze kann ja an
1110 // eine Textspalte gebunden gewesen sein, aber mit einem double koennen wir was anfangen)
1111 Date aDate
= DBTypeConversion::toDate(getDouble(aEffectiveDefault
));
1112 xNewProps
->setPropertyValue(sPropDefaultDate
, makeAny(aDate
));
1115 if (hasProperty(sPropDefaultTime
, xNewProps
) && !bIsString
)
1116 { // voellig analog mit Zeit
1117 Time aTime
= DBTypeConversion::toTime(getDouble(aEffectiveDefault
));
1118 xNewProps
->setPropertyValue(sPropDefaultTime
, makeAny(aTime
));
1121 if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE
), xNewProps
) && !bIsString
)
1122 { // hier koennen wir einfach das double durchreichen
1123 xNewProps
->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE
), aEffectiveDefault
);
1126 if (hasProperty(sPropDefaultText
, xNewProps
) && bIsString
)
1127 { // und hier den ::rtl::OUString
1128 xNewProps
->setPropertyValue(sPropDefaultText
, aEffectiveDefault
);
1131 // nyi: die Uebersetzung zwischen doubles und ::rtl::OUString wuerde noch mehr Moeglichkeien eroeffnen
1135 // die andere Richtung : das neu Control soll formatiert sein
1136 if (bNewIsFormatted
)
1138 // zuerst die Formatierung
1139 // einen Supplier koennen wir nicht setzen, also muss das neue Set schon einen mitbringen
1140 Reference
< XNumberFormatsSupplier
> xSupplier
;
1141 xNewProps
->getPropertyValue(sPropFormatsSupplier
) >>= xSupplier
;
1144 Reference
< XNumberFormats
> xFormats(xSupplier
->getNumberFormats());
1147 sal_Int16 nDecimals
= 2;
1148 if (hasProperty(sPropDecimalAccuracy
, xOldProps
))
1149 xOldProps
->getPropertyValue(sPropDecimalAccuracy
) >>= nDecimals
;
1151 // Grund-Format (je nach ClassId des alten Sets)
1152 sal_Int32 nBaseKey
= 0;
1153 if (hasProperty(sPropClassId
, xOldProps
))
1155 Reference
< XNumberFormatTypes
> xTypeList(xFormats
, UNO_QUERY
);
1158 sal_Int16 nClassId
= 0;
1159 xOldProps
->getPropertyValue(sPropClassId
) >>= nClassId
;
1162 case FormComponentType::DATEFIELD
:
1163 nBaseKey
= xTypeList
->getStandardFormat(NumberFormat::DATE
, _rLocale
);
1166 case FormComponentType::TIMEFIELD
:
1167 nBaseKey
= xTypeList
->getStandardFormat(NumberFormat::TIME
, _rLocale
);
1170 case FormComponentType::CURRENCYFIELD
:
1171 nBaseKey
= xTypeList
->getStandardFormat(NumberFormat::CURRENCY
, _rLocale
);
1177 // damit koennen wir ein neues Format basteln ...
1178 ::rtl::OUString sNewFormat
= xFormats
->generateFormat(nBaseKey
, _rLocale
, sal_False
, sal_False
, nDecimals
, 0);
1179 // kein Tausender-Trennzeichen, negative Zahlen nicht in Rot, keine fuehrenden Nullen
1181 // ... und zum FormatsSupplier hinzufuegen (wenn noetig)
1182 sal_Int32 nKey
= xFormats
->queryKey(sNewFormat
, _rLocale
, sal_False
);
1183 if (nKey
== (sal_Int32
)-1)
1184 { // noch nicht vorhanden in meinem Formatter ...
1185 nKey
= xFormats
->addNew(sNewFormat
, _rLocale
);
1188 xNewProps
->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY
), makeAny((sal_Int32
)nKey
));
1192 Any aNewMin
, aNewMax
;
1193 if (hasProperty(sPropValueMin
, xOldProps
))
1194 aNewMin
= xOldProps
->getPropertyValue(sPropValueMin
);
1195 if (hasProperty(sPropValueMax
, xOldProps
))
1196 aNewMax
= xOldProps
->getPropertyValue(sPropValueMax
);
1197 xNewProps
->setPropertyValue(sPropEffectiveMin
, aNewMin
);
1198 xNewProps
->setPropertyValue(sPropEffectiveMax
, aNewMax
);
1202 if (hasProperty(sPropDefaultDate
, xOldProps
))
1204 Any
aDate( xOldProps
->getPropertyValue(sPropDefaultDate
) );
1205 if (aDate
.hasValue())
1206 aNewDefault
<<= DBTypeConversion::toDouble(*(Date
*)aDate
.getValue());
1209 if (hasProperty(sPropDefaultTime
, xOldProps
))
1211 Any
aTime( xOldProps
->getPropertyValue(sPropDefaultTime
) );
1212 if (aTime
.hasValue())
1213 aNewDefault
<<= DBTypeConversion::toDouble(*(Time
*)aTime
.getValue());
1216 // double oder ::rtl::OUString werden direkt uebernommen
1217 if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE
), xOldProps
))
1218 aNewDefault
= xOldProps
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE
));
1219 if (hasProperty(sPropDefaultText
, xOldProps
))
1220 aNewDefault
= xOldProps
->getPropertyValue(sPropDefaultText
);
1222 if (aNewDefault
.hasValue())
1223 xNewProps
->setPropertyValue(sPropEffectiveDefault
, aNewDefault
);
1226 catch(const Exception
&)
1228 OSL_ENSURE( sal_False
, "TransferFormComponentProperties: caught an exception!" );
1232 //------------------------------------------------------------------------------
1233 sal_Bool
canInsert(const Reference
< XPropertySet
>& _rxCursorSet
)
1235 return ((_rxCursorSet
.is() && (getINT32(_rxCursorSet
->getPropertyValue(::rtl::OUString::createFromAscii("Privileges"))) & Privilege::INSERT
) != 0));
1238 //------------------------------------------------------------------------------
1239 sal_Bool
canUpdate(const Reference
< XPropertySet
>& _rxCursorSet
)
1241 return ((_rxCursorSet
.is() && (getINT32(_rxCursorSet
->getPropertyValue(::rtl::OUString::createFromAscii("Privileges"))) & Privilege::UPDATE
) != 0));
1244 //------------------------------------------------------------------------------
1245 sal_Bool
canDelete(const Reference
< XPropertySet
>& _rxCursorSet
)
1247 return ((_rxCursorSet
.is() && (getINT32(_rxCursorSet
->getPropertyValue(::rtl::OUString::createFromAscii("Privileges"))) & Privilege::DELETE
) != 0));
1249 // -----------------------------------------------------------------------------
1250 Reference
< XDataSource
> findDataSource(const Reference
< XInterface
>& _xParent
)
1252 Reference
< XOfficeDatabaseDocument
> xDatabaseDocument(_xParent
, UNO_QUERY
);
1253 Reference
< XDataSource
> xDataSource
;
1254 if ( xDatabaseDocument
.is() )
1255 xDataSource
= xDatabaseDocument
->getDataSource();
1256 if ( !xDataSource
.is() )
1257 xDataSource
.set(_xParent
, UNO_QUERY
);
1258 if (!xDataSource
.is())
1260 Reference
< XChild
> xChild(_xParent
, UNO_QUERY
);
1262 xDataSource
= findDataSource(xChild
->getParent());
1267 //------------------------------------------------------------------------------
1268 ::rtl::OUString
getComposedRowSetStatement( const Reference
< XPropertySet
>& _rxRowSet
, const Reference
< XMultiServiceFactory
>& _rxFactory
,
1269 sal_Bool _bUseRowSetFilter
, sal_Bool _bUseRowSetOrder
, Reference
< XSingleSelectQueryComposer
>* _pxComposer
)
1270 SAL_THROW( ( SQLException
) )
1272 ::rtl::OUString sStatement
;
1275 Reference
< XConnection
> xConn
= connectRowset( Reference
< XRowSet
>( _rxRowSet
, UNO_QUERY
), _rxFactory
, sal_True
);
1276 if ( xConn
.is() ) // implies _rxRowSet.is()
1278 // build the statement the row set is based on (can't use the ActiveCommand property of the set
1279 // as this reflects the status after the last execute, not the currently set properties)
1281 sal_Int32 nCommandType
= CommandType::COMMAND
;
1282 ::rtl::OUString sCommand
;
1283 sal_Bool bEscapeProcessing
= sal_False
;
1285 OSL_VERIFY( _rxRowSet
->getPropertyValue( ::rtl::OUString::createFromAscii( "CommandType" ) ) >>= nCommandType
);
1286 OSL_VERIFY( _rxRowSet
->getPropertyValue( ::rtl::OUString::createFromAscii( "Command" ) ) >>= sCommand
);
1287 OSL_VERIFY( _rxRowSet
->getPropertyValue( ::rtl::OUString::createFromAscii( "EscapeProcessing" ) ) >>= bEscapeProcessing
);
1289 StatementComposer
aComposer( xConn
, sCommand
, nCommandType
, bEscapeProcessing
);
1291 if ( _bUseRowSetOrder
)
1292 aComposer
.setOrder( getString( _rxRowSet
->getPropertyValue( ::rtl::OUString::createFromAscii( "Order" ) ) ) );
1295 if ( _bUseRowSetFilter
)
1297 sal_Bool bApplyFilter
= sal_True
;
1298 _rxRowSet
->getPropertyValue( ::rtl::OUString::createFromAscii( "ApplyFilter" ) ) >>= bApplyFilter
;
1300 aComposer
.setFilter( getString( _rxRowSet
->getPropertyValue( ::rtl::OUString::createFromAscii( "Filter" ) ) ) );
1303 sStatement
= aComposer
.getQuery();
1307 *_pxComposer
= aComposer
.getComposer();
1308 aComposer
.setDisposeComposer( false );
1312 catch( const SQLException
& )
1316 catch( const Exception
& )
1318 DBG_UNHANDLED_EXCEPTION();
1324 //------------------------------------------------------------------------------
1325 ::rtl::OUString
getComposedRowSetStatement(
1326 const Reference
< XPropertySet
>& _rxRowSet
, const Reference
< XMultiServiceFactory
>& _rxFactory
,
1327 sal_Bool _bUseRowSetFilter
, sal_Bool _bUseRowSetOrder
)
1329 return getComposedRowSetStatement( _rxRowSet
, _rxFactory
, _bUseRowSetFilter
, _bUseRowSetOrder
, NULL
);
1332 //------------------------------------------------------------------------------
1333 Reference
< XSingleSelectQueryComposer
> getCurrentSettingsComposer(
1334 const Reference
< XPropertySet
>& _rxRowSetProps
,
1335 const Reference
< XMultiServiceFactory
>& _rxFactory
)
1337 Reference
< XSingleSelectQueryComposer
> xReturn
;
1340 getComposedRowSetStatement( _rxRowSetProps
, _rxFactory
, sal_True
, sal_True
, &xReturn
);
1342 catch( const SQLException
& )
1346 catch( const Exception
& )
1348 OSL_ENSURE( sal_False
, "::getCurrentSettingsComposer : caught an exception !" );
1353 //--------------------------------------------------------------------------
1354 ::rtl::OUString
composeTableName( const Reference
< XDatabaseMetaData
>& _rxMetaData
,
1355 const ::rtl::OUString
& _rCatalog
,
1356 const ::rtl::OUString
& _rSchema
,
1357 const ::rtl::OUString
& _rName
,
1359 EComposeRule _eComposeRule
)
1361 return impl_doComposeTableName( _rxMetaData
, _rCatalog
, _rSchema
, _rName
, _bQuote
, _eComposeRule
);
1364 // -----------------------------------------------------------------------------
1365 ::rtl::OUString
composeTableNameForSelect( const Reference
< XConnection
>& _rxConnection
,
1366 const ::rtl::OUString
& _rCatalog
, const ::rtl::OUString
& _rSchema
, const ::rtl::OUString
& _rName
)
1368 sal_Bool bUseCatalogInSelect
= isDataSourcePropertyEnabled( _rxConnection
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseCatalogInSelect" ) ), sal_True
);
1369 sal_Bool bUseSchemaInSelect
= isDataSourcePropertyEnabled( _rxConnection
, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseSchemaInSelect" ) ), sal_True
);
1371 return impl_doComposeTableName(
1372 _rxConnection
->getMetaData(),
1373 bUseCatalogInSelect
? _rCatalog
: ::rtl::OUString(),
1374 bUseSchemaInSelect
? _rSchema
: ::rtl::OUString(),
1381 // -----------------------------------------------------------------------------
1384 static void lcl_getTableNameComponents( const Reference
<XPropertySet
>& _xTable
,
1385 ::rtl::OUString
& _out_rCatalog
, ::rtl::OUString
& _out_rSchema
, ::rtl::OUString
& _out_rName
)
1387 ::dbtools::OPropertyMap
& rPropMap
= OMetaConnection::getPropMap();
1388 Reference
< XPropertySetInfo
> xInfo
= _xTable
->getPropertySetInfo();
1390 && xInfo
->hasPropertyByName(rPropMap
.getNameByIndex(PROPERTY_ID_CATALOGNAME
))
1391 && xInfo
->hasPropertyByName(rPropMap
.getNameByIndex(PROPERTY_ID_SCHEMANAME
))
1392 && xInfo
->hasPropertyByName(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)) )
1395 ::rtl::OUString aCatalog
;
1396 ::rtl::OUString aSchema
;
1397 ::rtl::OUString aTable
;
1398 _xTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_CATALOGNAME
)) >>= _out_rCatalog
;
1399 _xTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_SCHEMANAME
)) >>= _out_rSchema
;
1400 _xTable
->getPropertyValue(rPropMap
.getNameByIndex(PROPERTY_ID_NAME
)) >>= _out_rName
;
1403 OSL_ENSURE( false, "::dbtools::lcl_getTableNameComponents: this is no table object!" );
1407 // -----------------------------------------------------------------------------
1408 ::rtl::OUString
composeTableNameForSelect( const Reference
< XConnection
>& _rxConnection
, const Reference
<XPropertySet
>& _xTable
)
1410 ::rtl::OUString sCatalog
, sSchema
, sName
;
1411 lcl_getTableNameComponents( _xTable
, sCatalog
, sSchema
, sName
);
1413 return composeTableNameForSelect( _rxConnection
, sCatalog
, sSchema
, sName
);
1416 // -----------------------------------------------------------------------------
1417 ::rtl::OUString
composeTableName(const Reference
<XDatabaseMetaData
>& _xMetaData
,
1418 const Reference
<XPropertySet
>& _xTable
,
1419 EComposeRule _eComposeRule
,
1420 bool _bSuppressCatalog
,
1421 bool _bSuppressSchema
,
1424 ::rtl::OUString sCatalog
, sSchema
, sName
;
1425 lcl_getTableNameComponents( _xTable
, sCatalog
, sSchema
, sName
);
1427 return impl_doComposeTableName(
1429 _bSuppressCatalog
? ::rtl::OUString() : sCatalog
,
1430 _bSuppressSchema
? ::rtl::OUString() : sSchema
,
1436 // -----------------------------------------------------------------------------
1437 sal_Int32
getSearchColumnFlag( const Reference
< XConnection
>& _rxConn
,sal_Int32 _nDataType
)
1439 sal_Int32 nSearchFlag
= 0;
1440 Reference
<XResultSet
> xSet
= _rxConn
->getMetaData()->getTypeInfo();
1443 Reference
<XRow
> xRow(xSet
,UNO_QUERY
);
1446 if(xRow
->getInt(2) == _nDataType
)
1448 nSearchFlag
= xRow
->getInt(9);
1456 // -----------------------------------------------------------------------------
1457 ::rtl::OUString
createUniqueName( const Sequence
< ::rtl::OUString
>& _rNames
, const ::rtl::OUString
& _rBaseName
, sal_Bool _bStartWithNumber
)
1459 ::std::set
< ::rtl::OUString
> aUsedNames
;
1461 _rNames
.getConstArray(),
1462 _rNames
.getConstArray() + _rNames
.getLength(),
1463 ::std::insert_iterator
< ::std::set
< ::rtl::OUString
> >( aUsedNames
, aUsedNames
.end() )
1466 ::rtl::OUString
sName( _rBaseName
);
1468 if ( _bStartWithNumber
)
1469 sName
+= ::rtl::OUString::valueOf( nPos
);
1471 while ( aUsedNames
.find( sName
) != aUsedNames
.end() )
1474 sName
+= ::rtl::OUString::valueOf( ++nPos
);
1479 // -----------------------------------------------------------------------------
1480 ::rtl::OUString
createUniqueName(const Reference
<XNameAccess
>& _rxContainer
,const ::rtl::OUString
& _rBaseName
,sal_Bool _bStartWithNumber
)
1482 Sequence
< ::rtl::OUString
> aElementNames
;
1484 OSL_ENSURE( _rxContainer
.is(), "createUniqueName: invalid container!" );
1485 if ( _rxContainer
.is() )
1486 aElementNames
= _rxContainer
->getElementNames();
1488 return createUniqueName( aElementNames
, _rBaseName
, _bStartWithNumber
);
1491 // -----------------------------------------------------------------------------
1492 void showError(const SQLExceptionInfo
& _rInfo
,
1493 const Reference
< XWindow
>& _xParent
,
1494 const Reference
< XMultiServiceFactory
>& _xFactory
)
1496 if (_rInfo
.isValid())
1500 Sequence
< Any
> aArgs(2);
1501 aArgs
[0] <<= PropertyValue(::rtl::OUString::createFromAscii("SQLException"), 0, _rInfo
.get(), PropertyState_DIRECT_VALUE
);
1502 aArgs
[1] <<= PropertyValue(::rtl::OUString::createFromAscii("ParentWindow"), 0, makeAny(_xParent
), PropertyState_DIRECT_VALUE
);
1504 static ::rtl::OUString s_sDialogServiceName
= ::rtl::OUString::createFromAscii("com.sun.star.sdb.ErrorMessageDialog");
1505 Reference
< XExecutableDialog
> xErrorDialog(
1506 _xFactory
->createInstanceWithArguments(s_sDialogServiceName
, aArgs
), UNO_QUERY
);
1507 if (xErrorDialog
.is())
1508 xErrorDialog
->execute();
1511 OSL_ENSURE(0,"dbtools::showError: no XExecutableDialog found!");
1516 OSL_ENSURE(0,"showError: could not display the error message!");
1521 // -------------------------------------------------------------------------
1522 sal_Bool
implUpdateObject(const Reference
< XRowUpdate
>& _rxUpdatedObject
,
1523 const sal_Int32 _nColumnIndex
, const Any
& _rValue
) SAL_THROW ( ( SQLException
, RuntimeException
) )
1525 sal_Bool bSuccessfullyReRouted
= sal_True
;
1526 switch (_rValue
.getValueTypeClass())
1531 _rValue
>>= aInnerValue
;
1532 bSuccessfullyReRouted
= implUpdateObject(_rxUpdatedObject
, _nColumnIndex
, aInnerValue
);
1536 case TypeClass_VOID
:
1537 _rxUpdatedObject
->updateNull(_nColumnIndex
);
1540 case TypeClass_STRING
:
1541 _rxUpdatedObject
->updateString(_nColumnIndex
, *(rtl::OUString
*)_rValue
.getValue());
1544 case TypeClass_BOOLEAN
:
1545 _rxUpdatedObject
->updateBoolean(_nColumnIndex
, *(sal_Bool
*)_rValue
.getValue());
1548 case TypeClass_BYTE
:
1549 _rxUpdatedObject
->updateByte(_nColumnIndex
, *(sal_Int8
*)_rValue
.getValue());
1552 case TypeClass_UNSIGNED_SHORT
:
1553 case TypeClass_SHORT
:
1554 _rxUpdatedObject
->updateShort(_nColumnIndex
, *(sal_Int16
*)_rValue
.getValue());
1557 case TypeClass_CHAR
:
1558 _rxUpdatedObject
->updateString(_nColumnIndex
,::rtl::OUString((sal_Unicode
*)_rValue
.getValue(),1));
1561 case TypeClass_UNSIGNED_LONG
:
1562 case TypeClass_LONG
:
1563 _rxUpdatedObject
->updateInt(_nColumnIndex
, *(sal_Int32
*)_rValue
.getValue());
1566 case TypeClass_HYPER
:
1568 sal_Int64 nValue
= 0;
1569 OSL_VERIFY( _rValue
>>= nValue
);
1570 _rxUpdatedObject
->updateLong( _nColumnIndex
, nValue
);
1574 case TypeClass_FLOAT
:
1575 _rxUpdatedObject
->updateFloat(_nColumnIndex
, *(float*)_rValue
.getValue());
1578 case TypeClass_DOUBLE
:
1579 _rxUpdatedObject
->updateDouble(_nColumnIndex
, *(double*)_rValue
.getValue());
1582 case TypeClass_SEQUENCE
:
1583 if (_rValue
.getValueType() == ::getCppuType((const Sequence
< sal_Int8
> *)0))
1584 _rxUpdatedObject
->updateBytes(_nColumnIndex
, *(Sequence
<sal_Int8
>*)_rValue
.getValue());
1586 bSuccessfullyReRouted
= sal_False
;
1588 case TypeClass_STRUCT
:
1589 if (_rValue
.getValueType() == ::getCppuType((const DateTime
*)0))
1590 _rxUpdatedObject
->updateTimestamp(_nColumnIndex
, *(DateTime
*)_rValue
.getValue());
1591 else if (_rValue
.getValueType() == ::getCppuType((const Date
*)0))
1592 _rxUpdatedObject
->updateDate(_nColumnIndex
, *(Date
*)_rValue
.getValue());
1593 else if (_rValue
.getValueType() == ::getCppuType((const Time
*)0))
1594 _rxUpdatedObject
->updateTime(_nColumnIndex
, *(Time
*)_rValue
.getValue());
1596 bSuccessfullyReRouted
= sal_False
;
1599 case TypeClass_INTERFACE
:
1600 if (_rValue
.getValueType() == ::getCppuType(static_cast<Reference
< XInputStream
>*>(NULL
)))
1602 Reference
< XInputStream
> xStream
;
1603 _rValue
>>= xStream
;
1604 _rxUpdatedObject
->updateBinaryStream(_nColumnIndex
, xStream
, xStream
->available());
1609 bSuccessfullyReRouted
= sal_False
;
1612 return bSuccessfullyReRouted
;
1614 // -------------------------------------------------------------------------
1615 sal_Bool
implSetObject( const Reference
< XParameters
>& _rxParameters
,
1616 const sal_Int32 _nColumnIndex
, const Any
& _rValue
) SAL_THROW ( ( SQLException
, RuntimeException
) )
1618 sal_Bool bSuccessfullyReRouted
= sal_True
;
1619 switch (_rValue
.getValueTypeClass())
1621 case TypeClass_HYPER
:
1623 sal_Int64 nValue
= 0;
1624 OSL_VERIFY( _rValue
>>= nValue
);
1625 _rxParameters
->setLong( _nColumnIndex
, nValue
);
1632 _rValue
>>= aInnerValue
;
1633 bSuccessfullyReRouted
= implSetObject(_rxParameters
, _nColumnIndex
, aInnerValue
);
1637 case TypeClass_VOID
:
1638 _rxParameters
->setNull(_nColumnIndex
,DataType::VARCHAR
);
1641 case TypeClass_STRING
:
1642 _rxParameters
->setString(_nColumnIndex
, *(rtl::OUString
*)_rValue
.getValue());
1645 case TypeClass_BOOLEAN
:
1646 _rxParameters
->setBoolean(_nColumnIndex
, *(sal_Bool
*)_rValue
.getValue());
1649 case TypeClass_BYTE
:
1650 _rxParameters
->setByte(_nColumnIndex
, *(sal_Int8
*)_rValue
.getValue());
1653 case TypeClass_UNSIGNED_SHORT
:
1654 case TypeClass_SHORT
:
1655 _rxParameters
->setShort(_nColumnIndex
, *(sal_Int16
*)_rValue
.getValue());
1658 case TypeClass_CHAR
:
1659 _rxParameters
->setString(_nColumnIndex
, ::rtl::OUString((sal_Unicode
*)_rValue
.getValue(),1));
1662 case TypeClass_UNSIGNED_LONG
:
1663 case TypeClass_LONG
:
1664 _rxParameters
->setInt(_nColumnIndex
, *(sal_Int32
*)_rValue
.getValue());
1667 case TypeClass_FLOAT
:
1668 _rxParameters
->setFloat(_nColumnIndex
, *(float*)_rValue
.getValue());
1671 case TypeClass_DOUBLE
:
1672 _rxParameters
->setDouble(_nColumnIndex
, *(double*)_rValue
.getValue());
1675 case TypeClass_SEQUENCE
:
1676 if (_rValue
.getValueType() == ::getCppuType((const Sequence
< sal_Int8
> *)0))
1678 _rxParameters
->setBytes(_nColumnIndex
, *(Sequence
<sal_Int8
>*)_rValue
.getValue());
1681 bSuccessfullyReRouted
= sal_False
;
1683 case TypeClass_STRUCT
:
1684 if (_rValue
.getValueType() == ::getCppuType((const DateTime
*)0))
1685 _rxParameters
->setTimestamp(_nColumnIndex
, *(DateTime
*)_rValue
.getValue());
1686 else if (_rValue
.getValueType() == ::getCppuType((const Date
*)0))
1687 _rxParameters
->setDate(_nColumnIndex
, *(Date
*)_rValue
.getValue());
1688 else if (_rValue
.getValueType() == ::getCppuType((const Time
*)0))
1689 _rxParameters
->setTime(_nColumnIndex
, *(Time
*)_rValue
.getValue());
1691 bSuccessfullyReRouted
= sal_False
;
1694 case TypeClass_INTERFACE
:
1695 if (_rValue
.getValueType() == ::getCppuType(static_cast<Reference
< XInputStream
>*>(NULL
)))
1697 Reference
< XInputStream
> xStream
;
1698 _rValue
>>= xStream
;
1699 _rxParameters
->setBinaryStream(_nColumnIndex
, xStream
, xStream
->available());
1704 bSuccessfullyReRouted
= sal_False
;
1708 return bSuccessfullyReRouted
;
1711 //..................................................................
1714 class OParameterWrapper
: public ::cppu::WeakImplHelper1
< XIndexAccess
>
1716 ::std::bit_vector m_aSet
;
1717 Reference
<XIndexAccess
> m_xSource
;
1719 OParameterWrapper(const ::std::bit_vector
& _aSet
,const Reference
<XIndexAccess
>& _xSource
) : m_aSet(_aSet
),m_xSource(_xSource
){}
1721 // ::com::sun::star::container::XElementAccess
1722 virtual Type SAL_CALL
getElementType() throw(RuntimeException
)
1724 return m_xSource
->getElementType();
1726 virtual sal_Bool SAL_CALL
hasElements( ) throw(RuntimeException
)
1728 if ( m_aSet
.empty() )
1729 return m_xSource
->hasElements();
1730 return ::std::count(m_aSet
.begin(),m_aSet
.end(),false) != 0;
1732 // ::com::sun::star::container::XIndexAccess
1733 virtual sal_Int32 SAL_CALL
getCount( ) throw(RuntimeException
)
1735 if ( m_aSet
.empty() )
1736 return m_xSource
->getCount();
1737 return ::std::count(m_aSet
.begin(),m_aSet
.end(),false);
1739 virtual Any SAL_CALL
getByIndex( sal_Int32 Index
) throw(IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
1741 if ( m_aSet
.empty() )
1742 return m_xSource
->getByIndex(Index
);
1743 if ( m_aSet
.size() < (size_t)Index
)
1744 throw IndexOutOfBoundsException();
1746 ::std::bit_vector::iterator aIter
= m_aSet
.begin();
1747 ::std::bit_vector::iterator aEnd
= m_aSet
.end();
1749 sal_Int32 nParamPos
= -1;
1750 for(; aIter
!= aEnd
&& i
<= Index
; ++aIter
)
1758 return m_xSource
->getByIndex(nParamPos
);
1763 // -----------------------------------------------------------------------------
1764 void askForParameters(const Reference
< XSingleSelectQueryComposer
>& _xComposer
,
1765 const Reference
<XParameters
>& _xParameters
,
1766 const Reference
< XConnection
>& _xConnection
,
1767 const Reference
< XInteractionHandler
>& _rxHandler
,
1768 const ::std::bit_vector
& _aParametersSet
)
1770 OSL_ENSURE(_xComposer
.is(),"dbtools::askForParameters XSQLQueryComposer is null!");
1771 OSL_ENSURE(_xParameters
.is(),"dbtools::askForParameters XParameters is null!");
1772 OSL_ENSURE(_xConnection
.is(),"dbtools::askForParameters XConnection is null!");
1773 OSL_ENSURE(_rxHandler
.is(),"dbtools::askForParameters XInteractionHandler is null!");
1775 // we have to set this here again because getCurrentSettingsComposer can force a setpropertyvalue
1776 Reference
<XParametersSupplier
> xParameters
= Reference
<XParametersSupplier
> (_xComposer
, UNO_QUERY
);
1778 Reference
<XIndexAccess
> xParamsAsIndicies
= xParameters
.is() ? xParameters
->getParameters() : Reference
<XIndexAccess
>();
1779 Reference
<XNameAccess
> xParamsAsNames(xParamsAsIndicies
, UNO_QUERY
);
1780 sal_Int32 nParamCount
= xParamsAsIndicies
.is() ? xParamsAsIndicies
->getCount() : 0;
1781 if ( (nParamCount
&& _aParametersSet
.empty()) || ::std::count(_aParametersSet
.begin(),_aParametersSet
.end(),true) != nParamCount
)
1783 // build an interaction request
1784 // two continuations (Ok and Cancel)
1785 OInteractionAbort
* pAbort
= new OInteractionAbort
;
1786 OParameterContinuation
* pParams
= new OParameterContinuation
;
1788 ParametersRequest aRequest
;
1789 Reference
<XIndexAccess
> xWrappedParameters
= new OParameterWrapper(_aParametersSet
,xParamsAsIndicies
);
1790 aRequest
.Parameters
= xWrappedParameters
;
1791 aRequest
.Connection
= _xConnection
;
1792 OInteractionRequest
* pRequest
= new OInteractionRequest(makeAny(aRequest
));
1793 Reference
< XInteractionRequest
> xRequest(pRequest
);
1795 pRequest
->addContinuation(pAbort
);
1796 pRequest
->addContinuation(pParams
);
1798 // execute the request
1799 _rxHandler
->handle(xRequest
);
1801 if (!pParams
->wasSelected())
1803 // canceled by the user (i.e. (s)he canceled the dialog)
1804 RowSetVetoException e
;
1805 e
.ErrorCode
= ParameterInteractionCancelled
;
1809 // now transfer the values from the continuation object to the parameter columns
1810 Sequence
< PropertyValue
> aFinalValues
= pParams
->getValues();
1811 const PropertyValue
* pFinalValues
= aFinalValues
.getConstArray();
1812 for (sal_Int32 i
=0; i
<aFinalValues
.getLength(); ++i
, ++pFinalValues
)
1814 Reference
< XPropertySet
> xParamColumn(xWrappedParameters
->getByIndex(i
),UNO_QUERY
);
1815 if (xParamColumn
.is())
1818 ::rtl::OUString sName
;
1819 xParamColumn
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME
)) >>= sName
;
1820 OSL_ENSURE(sName
.equals(pFinalValues
->Name
), "::dbaui::askForParameters: inconsistent parameter names!");
1822 // determine the field type and ...
1823 sal_Int32 nParamType
= 0;
1824 xParamColumn
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE
)) >>= nParamType
;
1825 // ... the scale of the parameter column
1826 sal_Int32 nScale
= 0;
1827 if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE
), xParamColumn
))
1828 xParamColumn
->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE
)) >>= nScale
;
1829 // and set the value
1830 ::std::bit_vector::const_iterator aIter
= _aParametersSet
.begin();
1831 ::std::bit_vector::const_iterator aEnd
= _aParametersSet
.end();
1833 sal_Int32 nParamPos
= -1;
1834 for(; aIter
!= aEnd
&& j
<= i
; ++aIter
)
1842 _xParameters
->setObjectWithInfo(nParamPos
+ 1, pFinalValues
->Value
, nParamType
, nScale
);
1843 // (the index of the parameters is one-based)
1848 // -----------------------------------------------------------------------------
1849 void setObjectWithInfo(const Reference
<XParameters
>& _xParams
,
1850 sal_Int32 parameterIndex
,
1853 sal_Int32
/*scale*/) throw(SQLException
, RuntimeException
)
1856 _xParams
->setNull(parameterIndex
,sqlType
);
1861 case DataType::DECIMAL
:
1862 case DataType::NUMERIC
:
1863 _xParams
->setObjectWithInfo(parameterIndex
,x
,sqlType
,0);
1865 case DataType::CHAR
:
1866 case DataType::VARCHAR
:
1867 //case DataType::DECIMAL:
1868 //case DataType::NUMERIC:
1869 case DataType::LONGVARCHAR
:
1870 _xParams
->setString(parameterIndex
,::comphelper::getString(x
));
1872 case DataType::BIGINT
:
1874 sal_Int64 nValue
= 0;
1877 _xParams
->setLong(parameterIndex
,nValue
);
1883 case DataType::FLOAT
:
1884 case DataType::REAL
:
1889 _xParams
->setFloat(parameterIndex
,nValue
);
1893 // run through if we couldn't set a float value
1894 case DataType::DOUBLE
:
1895 _xParams
->setDouble(parameterIndex
,::comphelper::getDouble(x
));
1897 case DataType::DATE
:
1899 ::com::sun::star::util::Date aValue
;
1901 _xParams
->setDate(parameterIndex
,aValue
);
1904 case DataType::TIME
:
1906 ::com::sun::star::util::Time aValue
;
1908 _xParams
->setTime(parameterIndex
,aValue
);
1911 case DataType::TIMESTAMP
:
1913 ::com::sun::star::util::DateTime aValue
;
1915 _xParams
->setTimestamp(parameterIndex
,aValue
);
1918 case DataType::BINARY
:
1919 case DataType::VARBINARY
:
1920 case DataType::LONGVARBINARY
:
1922 Sequence
< sal_Int8
> aBytes
;
1924 _xParams
->setBytes(parameterIndex
,aBytes
);
1927 Reference
< XBlob
> xBlob
;
1929 _xParams
->setBlob(parameterIndex
,xBlob
);
1932 Reference
< XClob
> xClob
;
1934 _xParams
->setClob(parameterIndex
,xClob
);
1937 Reference
< ::com::sun::star::io::XInputStream
> xBinStream
;
1938 if(x
>>= xBinStream
)
1939 _xParams
->setBinaryStream(parameterIndex
,xBinStream
,xBinStream
->available());
1946 case DataType::BOOLEAN
:
1947 _xParams
->setBoolean(parameterIndex
,::cppu::any2bool(x
));
1949 case DataType::TINYINT
:
1950 _xParams
->setByte(parameterIndex
,(sal_Int8
)::comphelper::getINT32(x
));
1952 case DataType::SMALLINT
:
1953 _xParams
->setShort(parameterIndex
,(sal_Int16
)::comphelper::getINT32(x
));
1955 case DataType::INTEGER
:
1956 _xParams
->setInt(parameterIndex
,::comphelper::getINT32(x
));
1960 ::connectivity::SharedResources aResources
;
1961 const ::rtl::OUString
sError( aResources
.getResourceStringWithSubstitution(
1962 STR_UNKNOWN_PARA_TYPE
,
1963 "$position$", ::rtl::OUString::valueOf(parameterIndex
)
1965 ::dbtools::throwGenericSQLException(sError
,NULL
);
1971 // --------------------------------------------------------------------
1972 void getBoleanComparisonPredicate( const ::rtl::OUString
& _rExpression
, const sal_Bool _bValue
, const sal_Int32 _nBooleanComparisonMode
,
1973 ::rtl::OUStringBuffer
& _out_rSQLPredicate
)
1975 switch ( _nBooleanComparisonMode
)
1977 case BooleanComparisonMode::IS_LITERAL
:
1978 _out_rSQLPredicate
.append( _rExpression
);
1980 _out_rSQLPredicate
.appendAscii( " IS TRUE" );
1982 _out_rSQLPredicate
.appendAscii( " IS FALSE" );
1985 case BooleanComparisonMode::EQUAL_LITERAL
:
1986 _out_rSQLPredicate
.append( _rExpression
);
1987 _out_rSQLPredicate
.appendAscii( _bValue
? " = TRUE" : " = FALSE" );
1990 case BooleanComparisonMode::ACCESS_COMPAT
:
1993 _out_rSQLPredicate
.appendAscii( " NOT ( ( " );
1994 _out_rSQLPredicate
.append( _rExpression
);
1995 _out_rSQLPredicate
.appendAscii( " = 0 ) OR ( " );
1996 _out_rSQLPredicate
.append( _rExpression
);
1997 _out_rSQLPredicate
.appendAscii( " IS NULL ) )" );
2001 _out_rSQLPredicate
.append( _rExpression
);
2002 _out_rSQLPredicate
.appendAscii( " = 0" );
2006 case BooleanComparisonMode::EQUAL_INTEGER
:
2009 _out_rSQLPredicate
.append( _rExpression
);
2010 _out_rSQLPredicate
.appendAscii( _bValue
? " = 1" : " = 0" );
2015 //.........................................................................
2016 } // namespace dbtools
2017 //.........................................................................
2019 //.........................................................................
2020 namespace connectivity
2022 //.........................................................................
2024 void release(oslInterlockedCount
& _refCount
,
2025 ::cppu::OBroadcastHelper
& rBHelper
,
2026 ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _xInterface
,
2027 ::com::sun::star::lang::XComponent
* _pObject
)
2029 if (osl_decrementInterlockedCount( &_refCount
) == 0)
2031 osl_incrementInterlockedCount( &_refCount
);
2033 if (!rBHelper
.bDisposed
&& !rBHelper
.bInDispose
)
2035 // remember the parent
2036 ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
> xParent
;
2038 ::osl::MutexGuard
aGuard( rBHelper
.rMutex
);
2039 xParent
= _xInterface
;
2044 _pObject
->dispose();
2046 // only the alive ref holds the object
2047 OSL_ASSERT( _refCount
== 1 );
2049 // release the parent in the ~
2052 ::osl::MutexGuard
aGuard( rBHelper
.rMutex
);
2053 _xInterface
= xParent
;
2056 // // destroy the object if xHoldAlive decrement the refcount to 0
2057 // m_pDerivedImplementation->WEAK::release();
2061 osl_incrementInterlockedCount( &_refCount
);
2064 void checkDisposed(sal_Bool _bThrow
) throw ( DisposedException
)
2067 throw DisposedException();
2070 // -------------------------------------------------------------------------
2071 OSQLColumns::Vector::const_iterator
find( OSQLColumns::Vector::const_iterator __first
,
2072 OSQLColumns::Vector::const_iterator __last
,
2073 const ::rtl::OUString
& _rVal
,
2074 const ::comphelper::UStringMixEqual
& _rCase
)
2076 ::rtl::OUString sName
= OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME
);
2077 return find(__first
,__last
,sName
,_rVal
,_rCase
);
2079 // -------------------------------------------------------------------------
2080 OSQLColumns::Vector::const_iterator
findRealName( OSQLColumns::Vector::const_iterator __first
,
2081 OSQLColumns::Vector::const_iterator __last
,
2082 const ::rtl::OUString
& _rVal
,
2083 const ::comphelper::UStringMixEqual
& _rCase
)
2085 ::rtl::OUString sRealName
= OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME
);
2086 return find(__first
,__last
,sRealName
,_rVal
,_rCase
);
2088 // -------------------------------------------------------------------------
2089 OSQLColumns::Vector::const_iterator
find( OSQLColumns::Vector::const_iterator __first
,
2090 OSQLColumns::Vector::const_iterator __last
,
2091 const ::rtl::OUString
& _rProp
,
2092 const ::rtl::OUString
& _rVal
,
2093 const ::comphelper::UStringMixEqual
& _rCase
)
2095 while (__first
!= __last
&& !_rCase(getString((*__first
)->getPropertyValue(_rProp
)),_rVal
))
2100 // -----------------------------------------------------------------------------
2101 } //namespace connectivity
2102 // -----------------------------------------------------------------------------