Update ooo320-m1
[ooovba.git] / connectivity / source / commontools / dbtools.cxx
blobeaf1d6fe8e56046f293c150fa754fd8134e3bd6a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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"
94 #include <algorithm>
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 //.........................................................................
112 namespace dbtools
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 //==============================================================================
129 namespace
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;
153 catch (Exception&)
155 return NumberFormat::UNDEFINED;
157 return getDefaultNumberFormat(nDataType,
158 nScale,
159 ::cppu::any2bool(_xColumn->getPropertyValue(::rtl::OUString::createFromAscii("IsCurrency"))),
160 _xTypes,
161 _rLocale);
164 //------------------------------------------------------------------
165 sal_Int32 getDefaultNumberFormat(sal_Int32 _nDataType,
166 sal_Int32 _nScale,
167 sal_Bool _bIsCurrency,
168 const Reference< XNumberFormatTypes >& _xTypes,
169 const Locale& _rLocale)
171 OSL_ENSURE(_xTypes.is() , "dbtools::getDefaultNumberFormat: invalid arg !");
172 if (!_xTypes.is())
173 return NumberFormat::UNDEFINED;
175 sal_Int32 nFormat = 0;
176 sal_Int32 nNumberType = _bIsCurrency ? NumberFormat::CURRENCY : NumberFormat::NUMBER;
177 switch (_nDataType)
179 case DataType::BIT:
180 case DataType::BOOLEAN:
181 nFormat = _xTypes->getStandardFormat(NumberFormat::LOGICAL, _rLocale);
182 break;
183 case DataType::TINYINT:
184 case DataType::SMALLINT:
185 case DataType::INTEGER:
186 case DataType::BIGINT:
187 case DataType::FLOAT:
188 case DataType::REAL:
189 case DataType::DOUBLE:
190 case DataType::NUMERIC:
191 case DataType::DECIMAL:
195 nFormat = _xTypes->getStandardFormat((sal_Int16)nNumberType, _rLocale);
196 if(_nScale > 0)
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);
208 catch (Exception&)
210 nFormat = _xTypes->getStandardFormat((sal_Int16)nNumberType, _rLocale);
212 } break;
213 case DataType::CHAR:
214 case DataType::VARCHAR:
215 case DataType::LONGVARCHAR:
216 nFormat = _xTypes->getStandardFormat(NumberFormat::TEXT, _rLocale);
217 break;
218 case DataType::DATE:
219 nFormat = _xTypes->getStandardFormat(NumberFormat::DATE, _rLocale);
220 break;
221 case DataType::TIME:
222 nFormat = _xTypes->getStandardFormat(NumberFormat::TIME, _rLocale);
223 break;
224 case DataType::TIMESTAMP:
225 nFormat = _xTypes->getStandardFormat(NumberFormat::DATETIME, _rLocale);
226 break;
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:
236 case DataType::BLOB:
237 case DataType::CLOB:
238 case DataType::REF:
239 default:
240 nFormat = NumberFormat::UNDEFINED;
242 return nFormat;
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);
253 if (xChild.is())
254 xConnection = findConnection(xChild->getParent());
256 return xConnection;
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 );
284 catch(Exception)
288 return xDS;
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;
314 catch(Exception&)
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!");
325 if (xHandler.is())
327 xConnection = xConnectionCompletion->connectWithCompletion(xHandler);
331 else
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);
337 return xConnection;
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);
350 catch(SQLException&)
352 // allowed to pass
353 throw;
355 catch(Exception&)
357 OSL_ENSURE(sal_False, "::dbtools::getConnection_withFeedback: unexpected (non-SQL) exception caught!");
359 return xReturn;
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);
374 catch(Exception&)
378 // TODO: if there were not dozens of places which rely on getConnection not throwing an exception ....
379 // I would change this ...
381 return xReturn;
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;
391 return 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() )
408 break;
410 // 1. already connected?
411 Reference< XConnection > xExistingConn(
412 xRowSetProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ActiveConnection" ) ) ),
413 UNO_QUERY );
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 );
429 break;
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 );
474 else
475 // just use the url
476 xPureConnection = xDriverManager->getConnection( sURL );
479 xConnection.reset(
480 xPureConnection,
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);
495 else
496 xRowSetProps->setPropertyValue(
497 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ActiveConnection" ) ),
498 makeAny( xConnection.getTyped() )
501 catch(Exception&)
503 OSL_ENSURE(0,"EXception when we set the new active connection!");
507 while ( false );
509 return xConnection;
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 //------------------------------------------------------------------------------
535 namespace
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;
555 // reset the error
556 if ( _pErrorInfo )
557 *_pErrorInfo = SQLExceptionInfo();
558 // reset the ownership holder
559 _rxKeepFieldsAlive.clear();
561 // go for the fields
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;
570 break;
571 case CommandType::QUERY:
572 eState = HANDLE_QUERY;
573 break;
574 case CommandType::COMMAND:
575 eState = HANDLE_SQL;
576 break;
579 // needed in various states:
580 Reference< XNameAccess > xObjectCollection;
581 Reference< XColumnsSupplier > xSupplyColumns;
583 // go!
584 while ( ( DONE != eState ) && ( FAILED != eState ) )
586 switch ( eState )
588 case HANDLE_TABLE:
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;
601 break;
603 case HANDLE_QUERY:
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;
616 break;
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
623 eState = 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;
637 break;
639 case RETRIEVE_COLUMNS:
640 OSL_ENSURE( xSupplyColumns.is(), "::dbtools::getFieldsByCommandDescriptor: could not retrieve the columns supplier!" );
642 // next state: default to FAILED
643 eState = FAILED;
645 if ( xSupplyColumns.is() )
647 xFields = xSupplyColumns->getColumns();
648 // that's it
649 eState = DONE;
651 break;
653 case HANDLE_SQL:
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
677 // result set.
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
689 // now execute
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;
720 break;
722 default:
723 OSL_ENSURE( sal_False, "::dbtools::getFieldsByCommandDescriptor: oops! unhandled state here!" );
724 eState = FAILED;
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!" );
736 return xFields;
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 );
756 // outta here
757 return aNames;
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 //--------------------------------------------------------------------------
775 namespace
777 struct NameComponentSupport
779 const bool bCatalogs;
780 const bool bSchemas;
782 NameComponentSupport( )
783 :bCatalogs( true )
784 ,bSchemas( true )
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;
808 break;
809 case eInIndexDefinitions:
810 pCatalogCall = &XDatabaseMetaData::supportsCatalogsInIndexDefinitions;
811 pSchemaCall = &XDatabaseMetaData::supportsSchemasInIndexDefinitions;
812 break;
813 case eInProcedureCalls:
814 pCatalogCall = &XDatabaseMetaData::supportsCatalogsInProcedureCalls;
815 pSchemaCall = &XDatabaseMetaData::supportsSchemasInProcedureCalls;
816 break;
817 case eInPrivilegeDefinitions:
818 pCatalogCall = &XDatabaseMetaData::supportsCatalogsInPrivilegeDefinitions;
819 pSchemaCall = &XDatabaseMetaData::supportsSchemasInPrivilegeDefinitions;
820 break;
821 case eComplete:
822 bIgnoreMetaData = true;
823 break;
824 case eInDataManipulation:
825 // already properly set above
826 break;
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()
873 && !bCatlogAtStart
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);
912 if (-1 != nIndex)
914 _rCatalog = sName.copy(0, nIndex);
915 sName = sName.copy(nIndex + 1);
918 else
920 // Katalogname am Ende
921 sal_Int32 nIndex = sName.lastIndexOf(sSeparator);
922 if (-1 != nIndex)
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!");
934 if ( nIndex != -1 )
935 _rSchema = sName.copy(0, nIndex);
936 sName = sName.copy(nIndex + 1);
939 _rName = sName;
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);
962 return xReturn;
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() )
976 return;
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))
1012 // binaere Suche
1013 Property* pResult = ::std::lower_bound(pNewProps, pNewProps + nNewLen,pOldProps[i].Name, ::comphelper::PropertyStringLessFunctor());
1014 if ( pResult
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)
1025 OSL_UNUSED( e );
1026 #ifdef DBG_UTIL
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));
1031 #endif
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 ;)
1050 return;
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;
1060 if (xSupplier.is())
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())
1090 { // analog
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;
1142 if (xSupplier.is())
1144 Reference< XNumberFormats> xFormats(xSupplier->getNumberFormats());
1146 // Dezimal-Stellen
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);
1156 if (xTypeList.is())
1158 sal_Int16 nClassId = 0;
1159 xOldProps->getPropertyValue(sPropClassId) >>= nClassId;
1160 switch (nClassId)
1162 case FormComponentType::DATEFIELD :
1163 nBaseKey = xTypeList->getStandardFormat(NumberFormat::DATE, _rLocale);
1164 break;
1166 case FormComponentType::TIMEFIELD :
1167 nBaseKey = xTypeList->getStandardFormat(NumberFormat::TIME, _rLocale);
1168 break;
1170 case FormComponentType::CURRENCYFIELD :
1171 nBaseKey = xTypeList->getStandardFormat(NumberFormat::CURRENCY, _rLocale);
1172 break;
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));
1191 // min-/max-Werte
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);
1200 // Default-Wert
1201 Any aNewDefault;
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);
1261 if ( xChild.is() )
1262 xDataSource = findDataSource(xChild->getParent());
1264 return xDataSource;
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 );
1290 // append sort
1291 if ( _bUseRowSetOrder )
1292 aComposer.setOrder( getString( _rxRowSet->getPropertyValue( ::rtl::OUString::createFromAscii( "Order" ) ) ) );
1294 // append filter
1295 if ( _bUseRowSetFilter )
1297 sal_Bool bApplyFilter = sal_True;
1298 _rxRowSet->getPropertyValue( ::rtl::OUString::createFromAscii( "ApplyFilter" ) ) >>= bApplyFilter;
1299 if ( bApplyFilter )
1300 aComposer.setFilter( getString( _rxRowSet->getPropertyValue( ::rtl::OUString::createFromAscii( "Filter" ) ) ) );
1303 sStatement = aComposer.getQuery();
1305 if ( _pxComposer )
1307 *_pxComposer = aComposer.getComposer();
1308 aComposer.setDisposeComposer( false );
1312 catch( const SQLException& )
1314 throw;
1316 catch( const Exception& )
1318 DBG_UNHANDLED_EXCEPTION();
1321 return sStatement;
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& )
1344 throw;
1346 catch( const Exception& )
1348 OSL_ENSURE( sal_False, "::getCurrentSettingsComposer : caught an exception !" );
1351 return xReturn;
1353 //--------------------------------------------------------------------------
1354 ::rtl::OUString composeTableName( const Reference< XDatabaseMetaData >& _rxMetaData,
1355 const ::rtl::OUString& _rCatalog,
1356 const ::rtl::OUString& _rSchema,
1357 const ::rtl::OUString& _rName,
1358 sal_Bool _bQuote,
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(),
1375 _rName,
1376 true,
1377 eInDataManipulation
1381 // -----------------------------------------------------------------------------
1382 namespace
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();
1389 if ( xInfo.is()
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;
1402 else
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,
1422 bool _bQuote )
1424 ::rtl::OUString sCatalog, sSchema, sName;
1425 lcl_getTableNameComponents( _xTable, sCatalog, sSchema, sName );
1427 return impl_doComposeTableName(
1428 _xMetaData,
1429 _bSuppressCatalog ? ::rtl::OUString() : sCatalog,
1430 _bSuppressSchema ? ::rtl::OUString() : sSchema,
1431 sName,
1432 _bQuote,
1433 _eComposeRule
1436 // -----------------------------------------------------------------------------
1437 sal_Int32 getSearchColumnFlag( const Reference< XConnection>& _rxConn,sal_Int32 _nDataType)
1439 sal_Int32 nSearchFlag = 0;
1440 Reference<XResultSet> xSet = _rxConn->getMetaData()->getTypeInfo();
1441 if(xSet.is())
1443 Reference<XRow> xRow(xSet,UNO_QUERY);
1444 while(xSet->next())
1446 if(xRow->getInt(2) == _nDataType)
1448 nSearchFlag = xRow->getInt(9);
1449 break;
1453 return nSearchFlag;
1456 // -----------------------------------------------------------------------------
1457 ::rtl::OUString createUniqueName( const Sequence< ::rtl::OUString >& _rNames, const ::rtl::OUString& _rBaseName, sal_Bool _bStartWithNumber )
1459 ::std::set< ::rtl::OUString > aUsedNames;
1460 ::std::copy(
1461 _rNames.getConstArray(),
1462 _rNames.getConstArray() + _rNames.getLength(),
1463 ::std::insert_iterator< ::std::set< ::rtl::OUString > >( aUsedNames, aUsedNames.end() )
1466 ::rtl::OUString sName( _rBaseName );
1467 sal_Int32 nPos = 1;
1468 if ( _bStartWithNumber )
1469 sName += ::rtl::OUString::valueOf( nPos );
1471 while ( aUsedNames.find( sName ) != aUsedNames.end() )
1473 sName = _rBaseName;
1474 sName += ::rtl::OUString::valueOf( ++nPos );
1476 return sName;
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();
1509 else
1511 OSL_ENSURE(0,"dbtools::showError: no XExecutableDialog found!");
1514 catch(Exception&)
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())
1528 case TypeClass_ANY:
1530 Any aInnerValue;
1531 _rValue >>= aInnerValue;
1532 bSuccessfullyReRouted = implUpdateObject(_rxUpdatedObject, _nColumnIndex, aInnerValue);
1534 break;
1536 case TypeClass_VOID:
1537 _rxUpdatedObject->updateNull(_nColumnIndex);
1538 break;
1540 case TypeClass_STRING:
1541 _rxUpdatedObject->updateString(_nColumnIndex, *(rtl::OUString*)_rValue.getValue());
1542 break;
1544 case TypeClass_BOOLEAN:
1545 _rxUpdatedObject->updateBoolean(_nColumnIndex, *(sal_Bool *)_rValue.getValue());
1546 break;
1548 case TypeClass_BYTE:
1549 _rxUpdatedObject->updateByte(_nColumnIndex, *(sal_Int8 *)_rValue.getValue());
1550 break;
1552 case TypeClass_UNSIGNED_SHORT:
1553 case TypeClass_SHORT:
1554 _rxUpdatedObject->updateShort(_nColumnIndex, *(sal_Int16*)_rValue.getValue());
1555 break;
1557 case TypeClass_CHAR:
1558 _rxUpdatedObject->updateString(_nColumnIndex,::rtl::OUString((sal_Unicode *)_rValue.getValue(),1));
1559 break;
1561 case TypeClass_UNSIGNED_LONG:
1562 case TypeClass_LONG:
1563 _rxUpdatedObject->updateInt(_nColumnIndex, *(sal_Int32*)_rValue.getValue());
1564 break;
1566 case TypeClass_HYPER:
1568 sal_Int64 nValue = 0;
1569 OSL_VERIFY( _rValue >>= nValue );
1570 _rxUpdatedObject->updateLong( _nColumnIndex, nValue );
1572 break;
1574 case TypeClass_FLOAT:
1575 _rxUpdatedObject->updateFloat(_nColumnIndex, *(float*)_rValue.getValue());
1576 break;
1578 case TypeClass_DOUBLE:
1579 _rxUpdatedObject->updateDouble(_nColumnIndex, *(double*)_rValue.getValue());
1580 break;
1582 case TypeClass_SEQUENCE:
1583 if (_rValue.getValueType() == ::getCppuType((const Sequence< sal_Int8 > *)0))
1584 _rxUpdatedObject->updateBytes(_nColumnIndex, *(Sequence<sal_Int8>*)_rValue.getValue());
1585 else
1586 bSuccessfullyReRouted = sal_False;
1587 break;
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());
1595 else
1596 bSuccessfullyReRouted = sal_False;
1597 break;
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());
1605 break;
1607 // run through
1608 default:
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 );
1627 break;
1629 case TypeClass_ANY:
1631 Any aInnerValue;
1632 _rValue >>= aInnerValue;
1633 bSuccessfullyReRouted = implSetObject(_rxParameters, _nColumnIndex, aInnerValue);
1635 break;
1637 case TypeClass_VOID:
1638 _rxParameters->setNull(_nColumnIndex,DataType::VARCHAR);
1639 break;
1641 case TypeClass_STRING:
1642 _rxParameters->setString(_nColumnIndex, *(rtl::OUString*)_rValue.getValue());
1643 break;
1645 case TypeClass_BOOLEAN:
1646 _rxParameters->setBoolean(_nColumnIndex, *(sal_Bool *)_rValue.getValue());
1647 break;
1649 case TypeClass_BYTE:
1650 _rxParameters->setByte(_nColumnIndex, *(sal_Int8 *)_rValue.getValue());
1651 break;
1653 case TypeClass_UNSIGNED_SHORT:
1654 case TypeClass_SHORT:
1655 _rxParameters->setShort(_nColumnIndex, *(sal_Int16*)_rValue.getValue());
1656 break;
1658 case TypeClass_CHAR:
1659 _rxParameters->setString(_nColumnIndex, ::rtl::OUString((sal_Unicode *)_rValue.getValue(),1));
1660 break;
1662 case TypeClass_UNSIGNED_LONG:
1663 case TypeClass_LONG:
1664 _rxParameters->setInt(_nColumnIndex, *(sal_Int32*)_rValue.getValue());
1665 break;
1667 case TypeClass_FLOAT:
1668 _rxParameters->setFloat(_nColumnIndex, *(float*)_rValue.getValue());
1669 break;
1671 case TypeClass_DOUBLE:
1672 _rxParameters->setDouble(_nColumnIndex, *(double*)_rValue.getValue());
1673 break;
1675 case TypeClass_SEQUENCE:
1676 if (_rValue.getValueType() == ::getCppuType((const Sequence< sal_Int8 > *)0))
1678 _rxParameters->setBytes(_nColumnIndex, *(Sequence<sal_Int8>*)_rValue.getValue());
1680 else
1681 bSuccessfullyReRouted = sal_False;
1682 break;
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());
1690 else
1691 bSuccessfullyReRouted = sal_False;
1692 break;
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());
1700 break;
1702 // run through
1703 default:
1704 bSuccessfullyReRouted = sal_False;
1708 return bSuccessfullyReRouted;
1711 //..................................................................
1712 namespace
1714 class OParameterWrapper : public ::cppu::WeakImplHelper1< XIndexAccess >
1716 ::std::bit_vector m_aSet;
1717 Reference<XIndexAccess> m_xSource;
1718 public:
1719 OParameterWrapper(const ::std::bit_vector& _aSet,const Reference<XIndexAccess>& _xSource) : m_aSet(_aSet),m_xSource(_xSource){}
1720 private:
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();
1748 sal_Int32 i = 0;
1749 sal_Int32 nParamPos = -1;
1750 for(; aIter != aEnd && i <= Index; ++aIter)
1752 ++nParamPos;
1753 if ( !*aIter )
1755 ++i;
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;
1787 // the request
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);
1794 // some knittings
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;
1806 throw e;
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())
1817 #ifdef DBG_UTIL
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!");
1821 #endif
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();
1832 sal_Int32 j = 0;
1833 sal_Int32 nParamPos = -1;
1834 for(; aIter != aEnd && j <= i; ++aIter)
1836 ++nParamPos;
1837 if ( !*aIter )
1839 ++j;
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,
1851 const Any& x,
1852 sal_Int32 sqlType,
1853 sal_Int32 /*scale*/) throw(SQLException, RuntimeException)
1855 if(!x.hasValue())
1856 _xParams->setNull(parameterIndex,sqlType);
1857 else
1859 switch(sqlType)
1861 case DataType::DECIMAL:
1862 case DataType::NUMERIC:
1863 _xParams->setObjectWithInfo(parameterIndex,x,sqlType,0);
1864 break;
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));
1871 break;
1872 case DataType::BIGINT:
1874 sal_Int64 nValue = 0;
1875 if(x >>= nValue)
1877 _xParams->setLong(parameterIndex,nValue);
1878 break;
1881 break;
1883 case DataType::FLOAT:
1884 case DataType::REAL:
1886 float nValue = 0;
1887 if(x >>= nValue)
1889 _xParams->setFloat(parameterIndex,nValue);
1890 break;
1893 // run through if we couldn't set a float value
1894 case DataType::DOUBLE:
1895 _xParams->setDouble(parameterIndex,::comphelper::getDouble(x));
1896 break;
1897 case DataType::DATE:
1899 ::com::sun::star::util::Date aValue;
1900 if(x >>= aValue)
1901 _xParams->setDate(parameterIndex,aValue);
1903 break;
1904 case DataType::TIME:
1906 ::com::sun::star::util::Time aValue;
1907 if(x >>= aValue)
1908 _xParams->setTime(parameterIndex,aValue);
1910 break;
1911 case DataType::TIMESTAMP:
1913 ::com::sun::star::util::DateTime aValue;
1914 if(x >>= aValue)
1915 _xParams->setTimestamp(parameterIndex,aValue);
1917 break;
1918 case DataType::BINARY:
1919 case DataType::VARBINARY:
1920 case DataType::LONGVARBINARY:
1922 Sequence< sal_Int8> aBytes;
1923 if(x >>= aBytes)
1924 _xParams->setBytes(parameterIndex,aBytes);
1925 else
1927 Reference< XBlob > xBlob;
1928 if(x >>= xBlob)
1929 _xParams->setBlob(parameterIndex,xBlob);
1930 else
1932 Reference< XClob > xClob;
1933 if(x >>= xClob)
1934 _xParams->setClob(parameterIndex,xClob);
1935 else
1937 Reference< ::com::sun::star::io::XInputStream > xBinStream;
1938 if(x >>= xBinStream)
1939 _xParams->setBinaryStream(parameterIndex,xBinStream,xBinStream->available());
1944 break;
1945 case DataType::BIT:
1946 case DataType::BOOLEAN:
1947 _xParams->setBoolean(parameterIndex,::cppu::any2bool(x));
1948 break;
1949 case DataType::TINYINT:
1950 _xParams->setByte(parameterIndex,(sal_Int8)::comphelper::getINT32(x));
1951 break;
1952 case DataType::SMALLINT:
1953 _xParams->setShort(parameterIndex,(sal_Int16)::comphelper::getINT32(x));
1954 break;
1955 case DataType::INTEGER:
1956 _xParams->setInt(parameterIndex,::comphelper::getINT32(x));
1957 break;
1958 default:
1960 ::connectivity::SharedResources aResources;
1961 const ::rtl::OUString sError( aResources.getResourceStringWithSubstitution(
1962 STR_UNKNOWN_PARA_TYPE,
1963 "$position$", ::rtl::OUString::valueOf(parameterIndex)
1964 ) );
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 );
1979 if ( _bValue )
1980 _out_rSQLPredicate.appendAscii( " IS TRUE" );
1981 else
1982 _out_rSQLPredicate.appendAscii( " IS FALSE" );
1983 break;
1985 case BooleanComparisonMode::EQUAL_LITERAL:
1986 _out_rSQLPredicate.append( _rExpression );
1987 _out_rSQLPredicate.appendAscii( _bValue ? " = TRUE" : " = FALSE" );
1988 break;
1990 case BooleanComparisonMode::ACCESS_COMPAT:
1991 if ( _bValue )
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 ) )" );
1999 else
2001 _out_rSQLPredicate.append( _rExpression );
2002 _out_rSQLPredicate.appendAscii( " = 0" );
2004 break;
2006 case BooleanComparisonMode::EQUAL_INTEGER:
2007 // fall through
2008 default:
2009 _out_rSQLPredicate.append( _rExpression );
2010 _out_rSQLPredicate.appendAscii( _bValue ? " = 1" : " = 0" );
2011 break;
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;
2040 _xInterface = NULL;
2043 // First dispose
2044 _pObject->dispose();
2046 // only the alive ref holds the object
2047 OSL_ASSERT( _refCount == 1 );
2049 // release the parent in the ~
2050 if (xParent.is())
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();
2060 else
2061 osl_incrementInterlockedCount( &_refCount );
2064 void checkDisposed(sal_Bool _bThrow) throw ( DisposedException )
2066 if (_bThrow)
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))
2096 ++__first;
2097 return __first;
2100 // -----------------------------------------------------------------------------
2101 } //namespace connectivity
2102 // -----------------------------------------------------------------------------