Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "connectivity/CommonTools.hxx"
21 : #include "diagnose_ex.h"
22 : #include "TConnection.hxx"
23 : #include "connectivity/ParameterCont.hxx"
24 :
25 : #include <com/sun/star/awt/XWindow.hpp>
26 : #include <com/sun/star/beans/PropertyAttribute.hpp>
27 : #include <com/sun/star/container/XChild.hpp>
28 : #include <com/sun/star/form/FormComponentType.hpp>
29 : #include <com/sun/star/io/XInputStream.hpp>
30 : #include <com/sun/star/lang/DisposedException.hpp>
31 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32 : #include <com/sun/star/sdb/DatabaseContext.hpp>
33 : #include <com/sun/star/sdb/BooleanComparisonMode.hpp>
34 : #include <com/sun/star/sdb/CommandType.hpp>
35 : #include <com/sun/star/sdb/ErrorMessageDialog.hpp>
36 : #include <com/sun/star/sdb/ParametersRequest.hpp>
37 : #include <com/sun/star/sdb/RowSetVetoException.hpp>
38 : #include <com/sun/star/sdb/SQLContext.hpp>
39 : #include <com/sun/star/sdb/XCompletedConnection.hpp>
40 : #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
41 : #include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
42 : #include <com/sun/star/sdb/XParametersSupplier.hpp>
43 : #include <com/sun/star/sdb/XQueriesSupplier.hpp>
44 : #include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
45 : #include <com/sun/star/sdbc/ConnectionPool.hpp>
46 : #include <com/sun/star/sdbc/DataType.hpp>
47 : #include <com/sun/star/sdbc/XConnection.hpp>
48 : #include <com/sun/star/sdbc/XDataSource.hpp>
49 : #include <com/sun/star/sdbc/XDriverManager.hpp>
50 : #include <com/sun/star/sdbc/XParameters.hpp>
51 : #include <com/sun/star/sdbc/XRow.hpp>
52 : #include <com/sun/star/sdbc/XRowSet.hpp>
53 : #include <com/sun/star/sdbc/XRowUpdate.hpp>
54 : #include <com/sun/star/sdbcx/KeyType.hpp>
55 : #include <com/sun/star/sdbcx/Privilege.hpp>
56 : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
57 : #include <com/sun/star/sdbcx/XKeysSupplier.hpp>
58 : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
59 : #include <com/sun/star/task/InteractionHandler.hpp>
60 : #include <com/sun/star/task/XInteractionRequest.hpp>
61 : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
62 : #include <com/sun/star/uno/XNamingService.hpp>
63 : #include <com/sun/star/util/NumberFormat.hpp>
64 : #include <com/sun/star/util/NumberFormatsSupplier.hpp>
65 : #include <com/sun/star/util/XNumberFormatTypes.hpp>
66 :
67 : #include <comphelper/extract.hxx>
68 : #include <comphelper/interaction.hxx>
69 : #include <comphelper/processfactory.hxx>
70 : #include <comphelper/property.hxx>
71 : #include <connectivity/conncleanup.hxx>
72 : #include <connectivity/dbconversion.hxx>
73 : #include <connectivity/dbexception.hxx>
74 : #include <connectivity/dbtools.hxx>
75 : #include <connectivity/statementcomposer.hxx>
76 : #include <osl/diagnose.h>
77 : #include <rtl/ustrbuf.hxx>
78 : #include <tools/diagnose_ex.h>
79 :
80 : #include "resource/common_res.hrc"
81 : #include "resource/sharedresources.hxx"
82 : #include "connectivity/OSubComponent.hxx"
83 :
84 : #include <algorithm>
85 : #include <iterator>
86 : #include <set>
87 :
88 : using namespace ::comphelper;
89 : using namespace ::com::sun::star::uno;
90 : using namespace ::com::sun::star::io;
91 : using namespace ::com::sun::star::awt;
92 : using namespace ::com::sun::star::ui::dialogs;
93 : using namespace ::com::sun::star::util;
94 : using namespace ::com::sun::star::lang;
95 : using namespace ::com::sun::star::beans;
96 : using namespace ::com::sun::star::container;
97 : using namespace ::com::sun::star::sdb;
98 : using namespace ::com::sun::star::sdbc;
99 : using namespace ::com::sun::star::sdbcx;
100 : using namespace ::com::sun::star::form;
101 : using namespace connectivity;
102 :
103 : namespace dbtools
104 : {
105 : using namespace ::com::sun::star::uno;
106 : using namespace ::com::sun::star::beans;
107 : using namespace ::com::sun::star::util;
108 : using namespace ::com::sun::star::lang;
109 : using namespace ::com::sun::star::sdbc;
110 : using namespace ::com::sun::star::task;
111 :
112 : namespace
113 : {
114 : typedef sal_Bool (SAL_CALL XDatabaseMetaData::*FMetaDataSupport)();
115 : }
116 :
117 0 : sal_Int32 getDefaultNumberFormat(const Reference< XPropertySet >& _xColumn,
118 : const Reference< XNumberFormatTypes >& _xTypes,
119 : const Locale& _rLocale)
120 : {
121 : OSL_ENSURE(_xTypes.is() && _xColumn.is(), "dbtools::getDefaultNumberFormat: invalid arg !");
122 0 : if (!_xTypes.is() || !_xColumn.is())
123 0 : return NumberFormat::UNDEFINED;
124 :
125 0 : sal_Int32 nDataType = 0;
126 0 : sal_Int32 nScale = 0;
127 : try
128 : {
129 : // determine the datatype of the column
130 0 : _xColumn->getPropertyValue("Type") >>= nDataType;
131 :
132 0 : if (DataType::NUMERIC == nDataType || DataType::DECIMAL == nDataType)
133 0 : _xColumn->getPropertyValue("Scale") >>= nScale;
134 : }
135 0 : catch (Exception&)
136 : {
137 0 : return NumberFormat::UNDEFINED;
138 : }
139 : return getDefaultNumberFormat(nDataType,
140 : nScale,
141 0 : ::cppu::any2bool(_xColumn->getPropertyValue("IsCurrency")),
142 : _xTypes,
143 0 : _rLocale);
144 : }
145 :
146 0 : sal_Int32 getDefaultNumberFormat(sal_Int32 _nDataType,
147 : sal_Int32 _nScale,
148 : bool _bIsCurrency,
149 : const Reference< XNumberFormatTypes >& _xTypes,
150 : const Locale& _rLocale)
151 : {
152 : OSL_ENSURE(_xTypes.is() , "dbtools::getDefaultNumberFormat: invalid arg !");
153 0 : if (!_xTypes.is())
154 0 : return NumberFormat::UNDEFINED;
155 :
156 0 : sal_Int32 nFormat = 0;
157 0 : sal_Int32 nNumberType = _bIsCurrency ? NumberFormat::CURRENCY : NumberFormat::NUMBER;
158 0 : switch (_nDataType)
159 : {
160 : case DataType::BIT:
161 : case DataType::BOOLEAN:
162 0 : nFormat = _xTypes->getStandardFormat(NumberFormat::LOGICAL, _rLocale);
163 0 : break;
164 : case DataType::TINYINT:
165 : case DataType::SMALLINT:
166 : case DataType::INTEGER:
167 : case DataType::BIGINT:
168 : case DataType::FLOAT:
169 : case DataType::REAL:
170 : case DataType::DOUBLE:
171 : case DataType::NUMERIC:
172 : case DataType::DECIMAL:
173 : {
174 : try
175 : {
176 0 : nFormat = _xTypes->getStandardFormat((sal_Int16)nNumberType, _rLocale);
177 0 : if(_nScale > 0)
178 : {
179 : // generate a new format if necessary
180 0 : Reference< XNumberFormats > xFormats(_xTypes, UNO_QUERY);
181 0 : OUString sNewFormat = xFormats->generateFormat( 0L, _rLocale, sal_False, sal_False, (sal_Int16)_nScale, sal_True);
182 :
183 : // and add it to the formatter if necessary
184 0 : nFormat = xFormats->queryKey(sNewFormat, _rLocale, sal_False);
185 0 : if (nFormat == (sal_Int32)-1)
186 0 : nFormat = xFormats->addNew(sNewFormat, _rLocale);
187 : }
188 : }
189 0 : catch (Exception&)
190 : {
191 0 : nFormat = _xTypes->getStandardFormat((sal_Int16)nNumberType, _rLocale);
192 : }
193 0 : } break;
194 : case DataType::CHAR:
195 : case DataType::VARCHAR:
196 : case DataType::LONGVARCHAR:
197 : case DataType::CLOB:
198 0 : nFormat = _xTypes->getStandardFormat(NumberFormat::TEXT, _rLocale);
199 0 : break;
200 : case DataType::DATE:
201 0 : nFormat = _xTypes->getStandardFormat(NumberFormat::DATE, _rLocale);
202 0 : break;
203 : case DataType::TIME:
204 0 : nFormat = _xTypes->getStandardFormat(NumberFormat::TIME, _rLocale);
205 0 : break;
206 : case DataType::TIMESTAMP:
207 0 : nFormat = _xTypes->getStandardFormat(NumberFormat::DATETIME, _rLocale);
208 0 : break;
209 : case DataType::BINARY:
210 : case DataType::VARBINARY:
211 : case DataType::LONGVARBINARY:
212 : case DataType::SQLNULL:
213 : case DataType::OTHER:
214 : case DataType::OBJECT:
215 : case DataType::DISTINCT:
216 : case DataType::STRUCT:
217 : case DataType::ARRAY:
218 : case DataType::BLOB:
219 : case DataType::REF:
220 : default:
221 0 : nFormat = _xTypes->getStandardFormat(NumberFormat::UNDEFINED, _rLocale);
222 : }
223 0 : return nFormat;
224 : }
225 :
226 0 : Reference< XConnection> findConnection(const Reference< XInterface >& xParent)
227 : {
228 0 : Reference< XConnection> xConnection(xParent, UNO_QUERY);
229 0 : if (!xConnection.is())
230 : {
231 0 : Reference< XChild> xChild(xParent, UNO_QUERY);
232 0 : if (xChild.is())
233 0 : xConnection = findConnection(xChild->getParent());
234 : }
235 0 : return xConnection;
236 : }
237 :
238 0 : Reference< XDataSource> getDataSource_allowException(
239 : const OUString& _rsTitleOrPath,
240 : const Reference< XComponentContext >& _rxContext )
241 : {
242 0 : ENSURE_OR_RETURN( !_rsTitleOrPath.isEmpty(), "getDataSource_allowException: invalid arg !", NULL );
243 :
244 0 : Reference< XDatabaseContext> xDatabaseContext = DatabaseContext::create(_rxContext);
245 :
246 0 : return Reference< XDataSource >( xDatabaseContext->getByName( _rsTitleOrPath ), UNO_QUERY );
247 : }
248 :
249 0 : Reference< XDataSource > getDataSource(
250 : const OUString& _rsTitleOrPath,
251 : const Reference< XComponentContext >& _rxContext )
252 : {
253 0 : Reference< XDataSource > xDS;
254 : try
255 : {
256 0 : xDS = getDataSource_allowException( _rsTitleOrPath, _rxContext );
257 : }
258 0 : catch( const Exception& )
259 : {
260 : DBG_UNHANDLED_EXCEPTION();
261 : }
262 :
263 0 : return xDS;
264 : }
265 :
266 0 : Reference< XConnection > getConnection_allowException(
267 : const OUString& _rsTitleOrPath,
268 : const OUString& _rsUser,
269 : const OUString& _rsPwd,
270 : const Reference< XComponentContext>& _rxContext)
271 : {
272 0 : Reference< XDataSource> xDataSource( getDataSource_allowException(_rsTitleOrPath, _rxContext) );
273 0 : Reference<XConnection> xConnection;
274 0 : if (xDataSource.is())
275 : {
276 : // do it with interaction handler
277 0 : if(_rsUser.isEmpty() || _rsPwd.isEmpty())
278 : {
279 0 : Reference<XPropertySet> xProp(xDataSource,UNO_QUERY);
280 0 : OUString sPwd, sUser;
281 0 : sal_Bool bPwdReq = sal_False;
282 : try
283 : {
284 0 : xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD)) >>= sPwd;
285 0 : bPwdReq = ::cppu::any2bool(xProp->getPropertyValue("IsPasswordRequired"));
286 0 : xProp->getPropertyValue("User") >>= sUser;
287 : }
288 0 : catch(Exception&)
289 : {
290 : OSL_FAIL("dbtools::getConnection: error while retrieving data source properties!");
291 : }
292 0 : if(bPwdReq && sPwd.isEmpty())
293 : { // password required, but empty -> connect using an interaction handler
294 0 : Reference<XCompletedConnection> xConnectionCompletion(xProp, UNO_QUERY);
295 0 : if (xConnectionCompletion.is())
296 : { // instantiate the default SDB interaction handler
297 : Reference< XInteractionHandler > xHandler(
298 0 : InteractionHandler::createWithParent(_rxContext, 0), UNO_QUERY );
299 0 : xConnection = xConnectionCompletion->connectWithCompletion(xHandler);
300 0 : }
301 : }
302 : else
303 0 : xConnection = xDataSource->getConnection(sUser, sPwd);
304 : }
305 0 : if(!xConnection.is()) // try to get one if not already have one, just to make sure
306 0 : xConnection = xDataSource->getConnection(_rsUser, _rsPwd);
307 : }
308 0 : return xConnection;
309 : }
310 :
311 0 : Reference< XConnection> getConnection_withFeedback(const OUString& _rDataSourceName,
312 : const OUString& _rUser, const OUString& _rPwd, const Reference< XComponentContext>& _rxContext)
313 : SAL_THROW ( (SQLException) )
314 : {
315 0 : Reference< XConnection > xReturn;
316 : try
317 : {
318 0 : xReturn = getConnection_allowException(_rDataSourceName, _rUser, _rPwd, _rxContext);
319 : }
320 0 : catch(SQLException&)
321 : {
322 : // allowed to pass
323 0 : throw;
324 : }
325 0 : catch(Exception&)
326 : {
327 : OSL_FAIL("::dbtools::getConnection_withFeedback: unexpected (non-SQL) exception caught!");
328 : }
329 0 : return xReturn;
330 : }
331 :
332 0 : Reference< XConnection> getConnection(const Reference< XRowSet>& _rxRowSet) throw (RuntimeException)
333 : {
334 0 : Reference< XConnection> xReturn;
335 0 : Reference< XPropertySet> xRowSetProps(_rxRowSet, UNO_QUERY);
336 0 : if (xRowSetProps.is())
337 0 : xRowSetProps->getPropertyValue("ActiveConnection") >>= xReturn;
338 0 : return xReturn;
339 : }
340 :
341 : // helper function which allows to implement both the connectRowset and the ensureRowSetConnection semantics
342 : // if connectRowset (which is deprecated) is removed, this function and one of its parameters are
343 : // not needed anymore, the whole implementation can be moved into ensureRowSetConnection then)
344 0 : SharedConnection lcl_connectRowSet(const Reference< XRowSet>& _rxRowSet, const Reference< XComponentContext >& _rxContext,
345 : bool _bSetAsActiveConnection, bool _bAttachAutoDisposer )
346 : SAL_THROW ( ( SQLException, WrappedTargetException, RuntimeException ) )
347 : {
348 0 : SharedConnection xConnection;
349 :
350 : do
351 : {
352 0 : Reference< XPropertySet> xRowSetProps(_rxRowSet, UNO_QUERY);
353 0 : if ( !xRowSetProps.is() )
354 0 : break;
355 :
356 : // 1. already connected?
357 : Reference< XConnection > xExistingConn(
358 0 : xRowSetProps->getPropertyValue("ActiveConnection"),
359 0 : UNO_QUERY );
360 :
361 0 : if ( xExistingConn.is()
362 : // 2. embedded in a database?
363 0 : || isEmbeddedInDatabase( _rxRowSet, xExistingConn )
364 : // 3. is there a connection in the parent hierarchy?
365 0 : || ( xExistingConn = findConnection( _rxRowSet ) ).is()
366 : )
367 : {
368 0 : if ( _bSetAsActiveConnection )
369 : {
370 0 : xRowSetProps->setPropertyValue("ActiveConnection", makeAny( xExistingConn ) );
371 : // no auto disposer needed, since we did not create the connection
372 : }
373 :
374 0 : xConnection.reset( xExistingConn, SharedConnection::NoTakeOwnership );
375 0 : break;
376 : }
377 :
378 : // build a connection with its current settings (4. data source name, or 5. URL)
379 :
380 0 : const OUString sUserProp( "User" );
381 0 : OUString sDataSourceName;
382 0 : xRowSetProps->getPropertyValue("DataSourceName") >>= sDataSourceName;
383 0 : OUString sURL;
384 0 : xRowSetProps->getPropertyValue("URL") >>= sURL;
385 :
386 0 : Reference< XConnection > xPureConnection;
387 0 : if (!sDataSourceName.isEmpty())
388 : { // the row set's data source property is set
389 : // -> try to connect, get user and pwd setting for that
390 0 : OUString sUser, sPwd;
391 :
392 0 : if (hasProperty(sUserProp, xRowSetProps))
393 0 : xRowSetProps->getPropertyValue(sUserProp) >>= sUser;
394 0 : if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD), xRowSetProps))
395 0 : xRowSetProps->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD)) >>= sPwd;
396 :
397 0 : xPureConnection = getConnection_allowException( sDataSourceName, sUser, sPwd, _rxContext );
398 : }
399 0 : else if (!sURL.isEmpty())
400 : { // the row set has no data source, but a connection url set
401 : // -> try to connection with that url
402 0 : Reference< XConnectionPool > xDriverManager;
403 : try {
404 0 : xDriverManager = ConnectionPool::create( _rxContext );
405 0 : } catch( const Exception& ) { }
406 0 : if (xDriverManager.is())
407 : {
408 0 : OUString sUser, sPwd;
409 0 : if (hasProperty(sUserProp, xRowSetProps))
410 0 : xRowSetProps->getPropertyValue(sUserProp) >>= sUser;
411 0 : if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD), xRowSetProps))
412 0 : xRowSetProps->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD)) >>= sPwd;
413 0 : if (!sUser.isEmpty())
414 : { // use user and pwd together with the url
415 0 : Sequence< PropertyValue> aInfo(2);
416 0 : aInfo.getArray()[0].Name = "user";
417 0 : aInfo.getArray()[0].Value <<= sUser;
418 0 : aInfo.getArray()[1].Name = "password";
419 0 : aInfo.getArray()[1].Value <<= sPwd;
420 0 : xPureConnection = xDriverManager->getConnectionWithInfo( sURL, aInfo );
421 : }
422 : else
423 : // just use the url
424 0 : xPureConnection = xDriverManager->getConnection( sURL );
425 0 : }
426 : }
427 : xConnection.reset(
428 : xPureConnection,
429 : _bAttachAutoDisposer ? SharedConnection::NoTakeOwnership : SharedConnection::TakeOwnership
430 : /* take ownership if and only if we're *not* going to auto-dispose the connection */
431 0 : );
432 :
433 : // now if we created a connection, forward it to the row set
434 0 : if ( xConnection.is() && _bSetAsActiveConnection )
435 : {
436 : try
437 : {
438 0 : if ( _bAttachAutoDisposer )
439 : {
440 0 : OAutoConnectionDisposer* pAutoDispose = new OAutoConnectionDisposer( _rxRowSet, xConnection );
441 0 : Reference< XPropertyChangeListener > xEnsureDelete(pAutoDispose);
442 : }
443 : else
444 0 : xRowSetProps->setPropertyValue(
445 : OUString( "ActiveConnection" ),
446 0 : makeAny( xConnection.getTyped() )
447 0 : );
448 : }
449 0 : catch(Exception&)
450 : {
451 : OSL_FAIL("EXception when we set the new active connection!");
452 : }
453 0 : }
454 : }
455 : while ( false );
456 :
457 0 : return xConnection;
458 : }
459 :
460 0 : Reference< XConnection> connectRowset(const Reference< XRowSet>& _rxRowSet, const Reference< XComponentContext >& _rxContext,
461 : bool _bSetAsActiveConnection ) SAL_THROW ( ( SQLException, WrappedTargetException, RuntimeException ) )
462 : {
463 0 : SharedConnection xConnection = lcl_connectRowSet( _rxRowSet, _rxContext, _bSetAsActiveConnection, true );
464 0 : return xConnection.getTyped();
465 : }
466 :
467 0 : SharedConnection ensureRowSetConnection(const Reference< XRowSet>& _rxRowSet, const Reference< XComponentContext>& _rxContext,
468 : bool _bUseAutoConnectionDisposer ) SAL_THROW ( ( SQLException, WrappedTargetException, RuntimeException ) )
469 : {
470 0 : return lcl_connectRowSet( _rxRowSet, _rxContext, true, _bUseAutoConnectionDisposer );
471 : }
472 :
473 0 : Reference< XNameAccess> getTableFields(const Reference< XConnection>& _rxConn,const OUString& _rName)
474 : {
475 0 : Reference< XComponent > xDummy;
476 0 : return getFieldsByCommandDescriptor( _rxConn, CommandType::TABLE, _rName, xDummy );
477 : }
478 :
479 0 : Reference< XNameAccess> getPrimaryKeyColumns_throw(const Any& i_aTable)
480 : {
481 0 : const Reference< XPropertySet > xTable(i_aTable,UNO_QUERY_THROW);
482 0 : return getPrimaryKeyColumns_throw(xTable);
483 : }
484 :
485 0 : Reference< XNameAccess> getPrimaryKeyColumns_throw(const Reference< XPropertySet >& i_xTable)
486 : {
487 0 : Reference<XNameAccess> xKeyColumns;
488 0 : const Reference<XKeysSupplier> xKeySup(i_xTable,UNO_QUERY);
489 0 : if ( xKeySup.is() )
490 : {
491 0 : const Reference<XIndexAccess> xKeys = xKeySup->getKeys();
492 0 : if ( xKeys.is() )
493 : {
494 0 : ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
495 0 : const OUString sPropName = rPropMap.getNameByIndex(PROPERTY_ID_TYPE);
496 0 : Reference<XPropertySet> xProp;
497 0 : const sal_Int32 nCount = xKeys->getCount();
498 0 : for(sal_Int32 i = 0;i< nCount;++i)
499 : {
500 0 : xProp.set(xKeys->getByIndex(i),UNO_QUERY_THROW);
501 0 : if ( xProp.is() )
502 : {
503 0 : sal_Int32 nKeyType = 0;
504 0 : xProp->getPropertyValue(sPropName) >>= nKeyType;
505 0 : if(KeyType::PRIMARY == nKeyType)
506 : {
507 0 : const Reference<XColumnsSupplier> xKeyColsSup(xProp,UNO_QUERY_THROW);
508 0 : xKeyColumns = xKeyColsSup->getColumns();
509 0 : break;
510 : }
511 : }
512 0 : }
513 0 : }
514 : }
515 :
516 0 : return xKeyColumns;
517 : }
518 :
519 : namespace
520 : {
521 : enum FieldLookupState
522 : {
523 : HANDLE_TABLE, HANDLE_QUERY, HANDLE_SQL, RETRIEVE_OBJECT, RETRIEVE_COLUMNS, DONE, FAILED
524 : };
525 : }
526 :
527 0 : Reference< XNameAccess > getFieldsByCommandDescriptor( const Reference< XConnection >& _rxConnection,
528 : const sal_Int32 _nCommandType, const OUString& _rCommand,
529 : Reference< XComponent >& _rxKeepFieldsAlive, SQLExceptionInfo* _pErrorInfo ) SAL_THROW( ( ) )
530 : {
531 : OSL_PRECOND( _rxConnection.is(), "::dbtools::getFieldsByCommandDescriptor: invalid connection!" );
532 : OSL_PRECOND( ( CommandType::TABLE == _nCommandType ) || ( CommandType::QUERY == _nCommandType ) || ( CommandType::COMMAND == _nCommandType ),
533 : "::dbtools::getFieldsByCommandDescriptor: invalid command type!" );
534 : OSL_PRECOND( !_rCommand.isEmpty(), "::dbtools::getFieldsByCommandDescriptor: invalid command (empty)!" );
535 :
536 0 : Reference< XNameAccess > xFields;
537 :
538 : // reset the error
539 0 : if ( _pErrorInfo )
540 0 : *_pErrorInfo = SQLExceptionInfo();
541 : // reset the ownership holder
542 0 : _rxKeepFieldsAlive.clear();
543 :
544 : // go for the fields
545 : try
546 : {
547 : // some kind of state machine to ease the sharing of code
548 0 : FieldLookupState eState = FAILED;
549 0 : switch ( _nCommandType )
550 : {
551 : case CommandType::TABLE:
552 0 : eState = HANDLE_TABLE;
553 0 : break;
554 : case CommandType::QUERY:
555 0 : eState = HANDLE_QUERY;
556 0 : break;
557 : case CommandType::COMMAND:
558 0 : eState = HANDLE_SQL;
559 0 : break;
560 : }
561 :
562 : // needed in various states:
563 0 : Reference< XNameAccess > xObjectCollection;
564 0 : Reference< XColumnsSupplier > xSupplyColumns;
565 :
566 : // go!
567 0 : while ( ( DONE != eState ) && ( FAILED != eState ) )
568 : {
569 0 : switch ( eState )
570 : {
571 : case HANDLE_TABLE:
572 : {
573 : // initial state for handling the tables
574 :
575 : // get the table objects
576 0 : Reference< XTablesSupplier > xSupplyTables( _rxConnection, UNO_QUERY );
577 0 : if ( xSupplyTables.is() )
578 0 : xObjectCollection = xSupplyTables->getTables();
579 : // if something went wrong 'til here, then this will be handled in the next state
580 :
581 : // next state: get the object
582 0 : eState = RETRIEVE_OBJECT;
583 : }
584 0 : break;
585 :
586 : case HANDLE_QUERY:
587 : {
588 : // initial state for handling the tables
589 :
590 : // get the table objects
591 0 : Reference< XQueriesSupplier > xSupplyQueries( _rxConnection, UNO_QUERY );
592 0 : if ( xSupplyQueries.is() )
593 0 : xObjectCollection = xSupplyQueries->getQueries();
594 : // if something went wrong 'til here, then this will be handled in the next state
595 :
596 : // next state: get the object
597 0 : eState = RETRIEVE_OBJECT;
598 : }
599 0 : break;
600 :
601 : case RETRIEVE_OBJECT:
602 : // here we should have an object (aka query or table) collection, and are going
603 : // to retrieve the desired object
604 :
605 : // next state: default to FAILED
606 0 : eState = FAILED;
607 :
608 : OSL_ENSURE( xObjectCollection.is(), "::dbtools::getFieldsByCommandDescriptor: invalid connection (no sdb.Connection, or no Tables-/QueriesSupplier)!");
609 0 : if ( xObjectCollection.is() )
610 : {
611 0 : if ( xObjectCollection.is() && xObjectCollection->hasByName( _rCommand ) )
612 : {
613 0 : xObjectCollection->getByName( _rCommand ) >>= xSupplyColumns;
614 : // (xSupplyColumns being NULL will be handled in the next state)
615 :
616 : // next: go for the columns
617 0 : eState = RETRIEVE_COLUMNS;
618 : }
619 : }
620 0 : break;
621 :
622 : case RETRIEVE_COLUMNS:
623 : OSL_ENSURE( xSupplyColumns.is(), "::dbtools::getFieldsByCommandDescriptor: could not retrieve the columns supplier!" );
624 :
625 : // next state: default to FAILED
626 0 : eState = FAILED;
627 :
628 0 : if ( xSupplyColumns.is() )
629 : {
630 0 : xFields = xSupplyColumns->getColumns();
631 : // that's it
632 0 : eState = DONE;
633 : }
634 0 : break;
635 :
636 : case HANDLE_SQL:
637 : {
638 0 : OUString sStatementToExecute( _rCommand );
639 :
640 : // well, the main problem here is to handle statements which contain a parameter
641 : // If we would simply execute a parametrized statement, then this will fail because
642 : // we cannot supply any parameter values.
643 : // Thus, we try to analyze the statement, and to append a WHERE 0=1 filter criterion
644 : // This should cause every driver to not really execute the statement, but to return
645 : // an empty result set with the proper structure. We then can use this result set
646 : // to retrieve the columns.
647 :
648 : try
649 : {
650 0 : Reference< XMultiServiceFactory > xComposerFac( _rxConnection, UNO_QUERY );
651 :
652 0 : if ( xComposerFac.is() )
653 : {
654 0 : Reference< XSingleSelectQueryComposer > xComposer(xComposerFac->createInstance("com.sun.star.sdb.SingleSelectQueryComposer"),UNO_QUERY);
655 0 : if ( xComposer.is() )
656 : {
657 0 : xComposer->setQuery( sStatementToExecute );
658 :
659 : // Now set the filter to a dummy restriction which will result in an empty
660 : // result set.
661 0 : xComposer->setFilter( OUString( "0=1" ) );
662 0 : sStatementToExecute = xComposer->getQuery( );
663 0 : }
664 0 : }
665 : }
666 0 : catch( const Exception& )
667 : {
668 : // silent this error, this was just a try. If we're here, we did not change sStatementToExecute,
669 : // so it will still be _rCommand, which then will be executed without being touched
670 : }
671 :
672 : // now execute
673 0 : Reference< XPreparedStatement > xStatement = _rxConnection->prepareStatement( sStatementToExecute );
674 : // transfer ownership of this temporary object to the caller
675 0 : _rxKeepFieldsAlive = _rxKeepFieldsAlive.query( xStatement );
676 :
677 : // set the "MaxRows" to 0. This is just in case our attempt to append a 0=1 filter
678 : // failed - in this case, the MaxRows restriction should at least ensure that there
679 : // is no data returned (which would be potentially expensive)
680 0 : Reference< XPropertySet > xStatementProps( xStatement,UNO_QUERY );
681 : try
682 : {
683 0 : if ( xStatementProps.is() )
684 0 : xStatementProps->setPropertyValue(
685 : OUString( "MaxRows" ),
686 : makeAny( sal_Int32( 0 ) )
687 0 : );
688 : }
689 0 : catch( const Exception& )
690 : {
691 : OSL_FAIL( "::dbtools::getFieldsByCommandDescriptor: could not set the MaxRows!" );
692 : // oh damn. Not much of a chance to recover, we will no retrieve the complete
693 : // full blown result set
694 : }
695 :
696 0 : xSupplyColumns = xSupplyColumns.query( xStatement->executeQuery() );
697 : // this should have given us a result set which does not contain any data, but
698 : // the structural information we need
699 :
700 : // so the next state is to get the columns
701 0 : eState = RETRIEVE_COLUMNS;
702 : }
703 0 : break;
704 :
705 : default:
706 : OSL_FAIL( "::dbtools::getFieldsByCommandDescriptor: oops! unhandled state here!" );
707 0 : eState = FAILED;
708 : }
709 0 : }
710 : }
711 0 : catch( const SQLContext& e ) { if ( _pErrorInfo ) *_pErrorInfo = SQLExceptionInfo( e ); }
712 0 : catch( const SQLWarning& e ) { if ( _pErrorInfo ) *_pErrorInfo = SQLExceptionInfo( e ); }
713 0 : catch( const SQLException& e ) { if ( _pErrorInfo ) *_pErrorInfo = SQLExceptionInfo( e ); }
714 0 : catch( const Exception& )
715 : {
716 : OSL_FAIL( "::dbtools::getFieldsByCommandDescriptor: caught an exception while retrieving the fields!" );
717 : }
718 :
719 0 : return xFields;
720 : }
721 :
722 0 : Sequence< OUString > getFieldNamesByCommandDescriptor( const Reference< XConnection >& _rxConnection,
723 : const sal_Int32 _nCommandType, const OUString& _rCommand,
724 : SQLExceptionInfo* _pErrorInfo ) SAL_THROW( ( ) )
725 : {
726 : // get the container for the fields
727 0 : Reference< XComponent > xKeepFieldsAlive;
728 0 : Reference< XNameAccess > xFieldContainer = getFieldsByCommandDescriptor( _rxConnection, _nCommandType, _rCommand, xKeepFieldsAlive, _pErrorInfo );
729 :
730 : // get the names of the fields
731 0 : Sequence< OUString > aNames;
732 0 : if ( xFieldContainer.is() )
733 0 : aNames = xFieldContainer->getElementNames();
734 :
735 : // clean up any temporary objects which have been created
736 0 : disposeComponent( xKeepFieldsAlive );
737 :
738 : // outta here
739 0 : return aNames;
740 : }
741 :
742 0 : SQLContext prependContextInfo(const SQLException& _rException, const Reference< XInterface >& _rxContext, const OUString& _rContextDescription, const OUString& _rContextDetails)
743 : {
744 0 : return SQLContext( _rContextDescription, _rxContext, OUString(), 0, makeAny( _rException ), _rContextDetails );
745 : }
746 :
747 0 : SQLException prependErrorInfo( const SQLException& _rChainedException, const Reference< XInterface >& _rxContext,
748 : const OUString& _rAdditionalError, const StandardSQLState _eSQLState, const sal_Int32 _nErrorCode )
749 : {
750 : return SQLException( _rAdditionalError, _rxContext,
751 : _eSQLState == SQL_ERROR_UNSPECIFIED ? OUString() : getStandardSQLState( _eSQLState ),
752 0 : _nErrorCode, makeAny( _rChainedException ) );
753 : }
754 :
755 : namespace
756 : {
757 : struct NameComponentSupport
758 : {
759 : const bool bCatalogs;
760 : const bool bSchemas;
761 :
762 0 : NameComponentSupport( const bool _bCatalogs, const bool _bSchemas )
763 : :bCatalogs( _bCatalogs )
764 0 : ,bSchemas( _bSchemas )
765 : {
766 0 : }
767 : };
768 :
769 0 : NameComponentSupport lcl_getNameComponentSupport( const Reference< XDatabaseMetaData >& _rxMetaData, EComposeRule _eComposeRule )
770 : {
771 : OSL_PRECOND( _rxMetaData.is(), "lcl_getNameComponentSupport: invalid meta data!" );
772 :
773 0 : FMetaDataSupport pCatalogCall = &XDatabaseMetaData::supportsCatalogsInDataManipulation;
774 0 : FMetaDataSupport pSchemaCall = &XDatabaseMetaData::supportsSchemasInDataManipulation;
775 0 : bool bIgnoreMetaData = false;
776 :
777 0 : switch ( _eComposeRule )
778 : {
779 : case eInTableDefinitions:
780 0 : pCatalogCall = &XDatabaseMetaData::supportsCatalogsInTableDefinitions;
781 0 : pSchemaCall = &XDatabaseMetaData::supportsSchemasInTableDefinitions;
782 0 : break;
783 : case eInIndexDefinitions:
784 0 : pCatalogCall = &XDatabaseMetaData::supportsCatalogsInIndexDefinitions;
785 0 : pSchemaCall = &XDatabaseMetaData::supportsSchemasInIndexDefinitions;
786 0 : break;
787 : case eInProcedureCalls:
788 0 : pCatalogCall = &XDatabaseMetaData::supportsCatalogsInProcedureCalls;
789 0 : pSchemaCall = &XDatabaseMetaData::supportsSchemasInProcedureCalls;
790 0 : break;
791 : case eInPrivilegeDefinitions:
792 0 : pCatalogCall = &XDatabaseMetaData::supportsCatalogsInPrivilegeDefinitions;
793 0 : pSchemaCall = &XDatabaseMetaData::supportsSchemasInPrivilegeDefinitions;
794 0 : break;
795 : case eComplete:
796 0 : bIgnoreMetaData = true;
797 0 : break;
798 : case eInDataManipulation:
799 : // already properly set above
800 0 : break;
801 : }
802 : return NameComponentSupport(
803 0 : bIgnoreMetaData ? true : (_rxMetaData.get()->*pCatalogCall)(),
804 0 : bIgnoreMetaData ? true : (_rxMetaData.get()->*pSchemaCall)()
805 0 : );
806 : }
807 : }
808 :
809 0 : static OUString impl_doComposeTableName( const Reference< XDatabaseMetaData >& _rxMetaData,
810 : const OUString& _rCatalog, const OUString& _rSchema, const OUString& _rName,
811 : bool _bQuote, EComposeRule _eComposeRule )
812 : {
813 : OSL_ENSURE(_rxMetaData.is(), "impl_doComposeTableName : invalid meta data !");
814 0 : if ( !_rxMetaData.is() )
815 0 : return OUString();
816 : OSL_ENSURE(!_rName.isEmpty(), "impl_doComposeTableName : at least the name should be non-empty !");
817 :
818 0 : const OUString sQuoteString = _rxMetaData->getIdentifierQuoteString();
819 0 : const NameComponentSupport aNameComps( lcl_getNameComponentSupport( _rxMetaData, _eComposeRule ) );
820 :
821 0 : OUStringBuffer aComposedName;
822 :
823 0 : OUString sCatalogSep;
824 0 : sal_Bool bCatlogAtStart = sal_True;
825 0 : if ( !_rCatalog.isEmpty() && aNameComps.bCatalogs )
826 : {
827 0 : sCatalogSep = _rxMetaData->getCatalogSeparator();
828 0 : bCatlogAtStart = _rxMetaData->isCatalogAtStart();
829 :
830 0 : if ( bCatlogAtStart && !sCatalogSep.isEmpty())
831 : {
832 0 : aComposedName.append( _bQuote ? quoteName( sQuoteString, _rCatalog ) : _rCatalog );
833 0 : aComposedName.append( sCatalogSep );
834 : }
835 : }
836 :
837 0 : if ( !_rSchema.isEmpty() && aNameComps.bSchemas )
838 : {
839 0 : aComposedName.append( _bQuote ? quoteName( sQuoteString, _rSchema ) : _rSchema );
840 0 : aComposedName.appendAscii( "." );
841 : }
842 :
843 0 : aComposedName.append( _bQuote ? quoteName( sQuoteString, _rName ) : _rName );
844 :
845 0 : if ( !_rCatalog.isEmpty()
846 0 : && !bCatlogAtStart
847 0 : && !sCatalogSep.isEmpty()
848 0 : && aNameComps.bCatalogs
849 : )
850 : {
851 0 : aComposedName.append( sCatalogSep );
852 0 : aComposedName.append( _bQuote ? quoteName( sQuoteString, _rCatalog ) : _rCatalog );
853 : }
854 :
855 0 : return aComposedName.makeStringAndClear();
856 : }
857 :
858 0 : OUString quoteTableName(const Reference< XDatabaseMetaData>& _rxMeta
859 : , const OUString& _rName
860 : , EComposeRule _eComposeRule)
861 : {
862 0 : OUString sCatalog, sSchema, sTable;
863 0 : qualifiedNameComponents(_rxMeta,_rName,sCatalog,sSchema,sTable,_eComposeRule);
864 0 : return impl_doComposeTableName( _rxMeta, sCatalog, sSchema, sTable, true, _eComposeRule );
865 : }
866 :
867 0 : void qualifiedNameComponents(const Reference< XDatabaseMetaData >& _rxConnMetaData, const OUString& _rQualifiedName, OUString& _rCatalog, OUString& _rSchema, OUString& _rName,EComposeRule _eComposeRule)
868 : {
869 : OSL_ENSURE(_rxConnMetaData.is(), "QualifiedNameComponents : invalid meta data!");
870 :
871 0 : NameComponentSupport aNameComps( lcl_getNameComponentSupport( _rxConnMetaData, _eComposeRule ) );
872 :
873 0 : OUString sSeparator = _rxConnMetaData->getCatalogSeparator();
874 :
875 0 : OUString sName(_rQualifiedName);
876 : // do we have catalogs ?
877 0 : if ( aNameComps.bCatalogs )
878 : {
879 0 : if (_rxConnMetaData->isCatalogAtStart())
880 : {
881 : // search for the catalog name at the beginning
882 0 : sal_Int32 nIndex = sName.indexOf(sSeparator);
883 0 : if (-1 != nIndex)
884 : {
885 0 : _rCatalog = sName.copy(0, nIndex);
886 0 : sName = sName.copy(nIndex + 1);
887 : }
888 : }
889 : else
890 : {
891 : // Catalogue name at the end
892 0 : sal_Int32 nIndex = sName.lastIndexOf(sSeparator);
893 0 : if (-1 != nIndex)
894 : {
895 0 : _rCatalog = sName.copy(nIndex + 1);
896 0 : sName = sName.copy(0, nIndex);
897 : }
898 : }
899 : }
900 :
901 0 : if ( aNameComps.bSchemas )
902 : {
903 0 : sal_Int32 nIndex = sName.indexOf((sal_Unicode)'.');
904 : // OSL_ENSURE(-1 != nIndex, "QualifiedNameComponents : no schema separator!");
905 0 : if ( nIndex != -1 )
906 0 : _rSchema = sName.copy(0, nIndex);
907 0 : sName = sName.copy(nIndex + 1);
908 : }
909 :
910 0 : _rName = sName;
911 0 : }
912 :
913 0 : Reference< XNumberFormatsSupplier> getNumberFormats(
914 : const Reference< XConnection>& _rxConn,
915 : bool _bAlloweDefault,
916 : const Reference< XComponentContext>& _rxContext)
917 : {
918 : // ask the parent of the connection (should be an DatabaseAccess)
919 0 : Reference< XNumberFormatsSupplier> xReturn;
920 0 : Reference< XChild> xConnAsChild(_rxConn, UNO_QUERY);
921 0 : OUString sPropFormatsSupplier( "NumberFormatsSupplier" );
922 0 : if (xConnAsChild.is())
923 : {
924 0 : Reference< XPropertySet> xConnParentProps(xConnAsChild->getParent(), UNO_QUERY);
925 0 : if (xConnParentProps.is() && hasProperty(sPropFormatsSupplier, xConnParentProps))
926 0 : xConnParentProps->getPropertyValue(sPropFormatsSupplier) >>= xReturn;
927 : }
928 0 : else if(_bAlloweDefault && _rxContext.is())
929 : {
930 0 : xReturn = NumberFormatsSupplier::createWithDefaultLocale( _rxContext );
931 : }
932 0 : return xReturn;
933 : }
934 :
935 0 : void TransferFormComponentProperties(
936 : const Reference< XPropertySet>& xOldProps,
937 : const Reference< XPropertySet>& xNewProps,
938 : const Locale& _rLocale)
939 : {
940 : try
941 : {
942 : OSL_ENSURE( xOldProps.is() && xNewProps.is(), "TransferFormComponentProperties: invalid source/dest!" );
943 0 : if ( !xOldProps.is() || !xNewProps.is() )
944 0 : return;
945 :
946 : // First we copy all the Props, that are available in source and target and have the same description
947 0 : Reference< XPropertySetInfo> xOldInfo( xOldProps->getPropertySetInfo());
948 0 : Reference< XPropertySetInfo> xNewInfo( xNewProps->getPropertySetInfo());
949 :
950 0 : Sequence< Property> aOldProperties = xOldInfo->getProperties();
951 0 : Sequence< Property> aNewProperties = xNewInfo->getProperties();
952 0 : int nNewLen = aNewProperties.getLength();
953 :
954 0 : Property* pOldProps = aOldProperties.getArray();
955 0 : Property* pNewProps = aNewProperties.getArray();
956 :
957 0 : OUString sPropDefaultControl("DefaultControl");
958 0 : OUString sPropLabelControl("LabelControl");
959 0 : OUString sPropFormatsSupplier("FormatsSupplier");
960 0 : OUString sPropCurrencySymbol("CurrencySymbol");
961 0 : OUString sPropDecimals("Decimals");
962 0 : OUString sPropEffectiveMin("EffectiveMin");
963 0 : OUString sPropEffectiveMax("EffectiveMax");
964 0 : OUString sPropEffectiveDefault("EffectiveDefault");
965 0 : OUString sPropDefaultText("DefaultText");
966 0 : OUString sPropDefaultDate("DefaultDate");
967 0 : OUString sPropDefaultTime("DefaultTime");
968 0 : OUString sPropValueMin("ValueMin");
969 0 : OUString sPropValueMax("ValueMax");
970 0 : OUString sPropDecimalAccuracy("DecimalAccuracy");
971 0 : OUString sPropClassId("ClassId");
972 0 : OUString sFormattedServiceName( "com.sun.star.form.component.FormattedField" );
973 :
974 0 : for (sal_Int16 i=0; i<aOldProperties.getLength(); ++i)
975 : {
976 0 : if ( (!pOldProps[i].Name.equals(sPropDefaultControl))
977 0 : && (!pOldProps[i].Name.equals(sPropLabelControl))
978 : )
979 : {
980 : // binary search
981 : Property* pResult = ::std::lower_bound(
982 0 : pNewProps, pNewProps + nNewLen, pOldProps[i], ::comphelper::PropertyCompareByName());
983 :
984 0 : if ( pResult
985 0 : && ( pResult != pNewProps + nNewLen && pResult->Name == pOldProps[i].Name )
986 0 : && ( (pResult->Attributes & PropertyAttribute::READONLY) == 0 )
987 0 : && ( pResult->Type.equals(pOldProps[i].Type)) )
988 : { // Attributes match and the property is not read-only
989 : try
990 : {
991 0 : xNewProps->setPropertyValue(pResult->Name, xOldProps->getPropertyValue(pResult->Name));
992 : }
993 0 : catch(IllegalArgumentException& e)
994 : {
995 : OSL_UNUSED( e );
996 : #ifdef DBG_UTIL
997 : OUString sMessage = "TransferFormComponentProperties : could not transfer the value for property \"" +
998 : pResult->Name +
999 : "\"";
1000 : OSL_FAIL(OUStringToOString(sMessage, RTL_TEXTENCODING_ASCII_US).getStr());
1001 : #endif
1002 : }
1003 : }
1004 : }
1005 : }
1006 :
1007 : // for formatted fields (either old or new) we have some special treatments
1008 0 : Reference< XServiceInfo > xSI( xOldProps, UNO_QUERY );
1009 0 : sal_Bool bOldIsFormatted = xSI.is() && xSI->supportsService( sFormattedServiceName );
1010 0 : xSI = Reference< XServiceInfo >( xNewProps, UNO_QUERY );
1011 0 : sal_Bool bNewIsFormatted = xSI.is() && xSI->supportsService( sFormattedServiceName );
1012 :
1013 0 : if (!bOldIsFormatted && !bNewIsFormatted)
1014 0 : return; // nothing to do
1015 :
1016 0 : if (bOldIsFormatted && bNewIsFormatted)
1017 : // if both fields are formatted we do no conversions
1018 0 : return;
1019 :
1020 0 : if (bOldIsFormatted)
1021 : {
1022 : // get some properties from the selected format and put them in the new Set
1023 0 : Any aFormatKey( xOldProps->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY)) );
1024 0 : if (aFormatKey.hasValue())
1025 : {
1026 0 : Reference< XNumberFormatsSupplier> xSupplier;
1027 0 : xOldProps->getPropertyValue(sPropFormatsSupplier) >>= xSupplier;
1028 0 : if (xSupplier.is())
1029 : {
1030 0 : Reference< XNumberFormats> xFormats(xSupplier->getNumberFormats());
1031 0 : Reference< XPropertySet> xFormat(xFormats->getByKey(getINT32(aFormatKey)));
1032 0 : if (hasProperty(sPropCurrencySymbol, xFormat))
1033 : {
1034 0 : Any aVal( xFormat->getPropertyValue(sPropCurrencySymbol) );
1035 0 : if (aVal.hasValue() && hasProperty(sPropCurrencySymbol, xNewProps))
1036 : // If the source value hasn't been set then don't copy it
1037 : // so we don't overwrite the default value
1038 0 : xNewProps->setPropertyValue(sPropCurrencySymbol, aVal);
1039 : }
1040 0 : if (hasProperty(sPropDecimals, xFormat) && hasProperty(sPropDecimals, xNewProps))
1041 0 : xNewProps->setPropertyValue(sPropDecimals, xFormat->getPropertyValue(sPropDecimals));
1042 0 : }
1043 : }
1044 :
1045 : // a potential Min-Max-Conversion
1046 0 : Any aEffectiveMin( xOldProps->getPropertyValue(sPropEffectiveMin) );
1047 0 : if (aEffectiveMin.hasValue())
1048 : { // Unlike the ValueMin the EffectiveMin can be void
1049 0 : if (hasProperty(sPropValueMin, xNewProps))
1050 : {
1051 : OSL_ENSURE(aEffectiveMin.getValueType().getTypeClass() == TypeClass_DOUBLE,
1052 : "TransferFormComponentProperties : invalid property type !");
1053 0 : xNewProps->setPropertyValue(sPropValueMin, aEffectiveMin);
1054 : }
1055 : }
1056 0 : Any aEffectiveMax( xOldProps->getPropertyValue(sPropEffectiveMax) );
1057 0 : if (aEffectiveMax.hasValue())
1058 : { // analog
1059 0 : if (hasProperty(sPropValueMax, xNewProps))
1060 : {
1061 : OSL_ENSURE(aEffectiveMax.getValueType().getTypeClass() == TypeClass_DOUBLE,
1062 : "TransferFormComponentProperties : invalid property type !");
1063 0 : xNewProps->setPropertyValue(sPropValueMax, aEffectiveMax);
1064 : }
1065 : }
1066 :
1067 : // then we can still convert and copy the default values
1068 0 : Any aEffectiveDefault( xOldProps->getPropertyValue(sPropEffectiveDefault) );
1069 0 : if (aEffectiveDefault.hasValue())
1070 : {
1071 0 : sal_Bool bIsString = aEffectiveDefault.getValueType().getTypeClass() == TypeClass_STRING;
1072 : OSL_ENSURE(bIsString || aEffectiveDefault.getValueType().getTypeClass() == TypeClass_DOUBLE,
1073 : "TransferFormComponentProperties : invalid property type !");
1074 : // The Effective-Properties should always be void or string or double ....
1075 :
1076 0 : if (hasProperty(sPropDefaultDate, xNewProps) && !bIsString)
1077 : { // (to convert a OUString into a date will not always succeed, because it might be bound to a text-column,
1078 : // but we can work with a double)
1079 0 : Date aDate = DBTypeConversion::toDate(getDouble(aEffectiveDefault));
1080 0 : xNewProps->setPropertyValue(sPropDefaultDate, makeAny(aDate));
1081 : }
1082 :
1083 0 : if (hasProperty(sPropDefaultTime, xNewProps) && !bIsString)
1084 : { // Completely analogous to time
1085 0 : Time aTime = DBTypeConversion::toTime(getDouble(aEffectiveDefault));
1086 0 : xNewProps->setPropertyValue(sPropDefaultTime, makeAny(aTime));
1087 : }
1088 :
1089 0 : if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE), xNewProps) && !bIsString)
1090 : { // Here we can simply pass the double
1091 0 : xNewProps->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE), aEffectiveDefault);
1092 : }
1093 :
1094 0 : if (hasProperty(sPropDefaultText, xNewProps) && bIsString)
1095 : { // and here the OUString
1096 0 : xNewProps->setPropertyValue(sPropDefaultText, aEffectiveDefault);
1097 : }
1098 :
1099 : // nyi: The translation between doubles and OUString would offer more alternatives
1100 0 : }
1101 : }
1102 :
1103 : // The other direction: the new Control shall be formatted
1104 0 : if (bNewIsFormatted)
1105 : {
1106 : // first the formatting
1107 : // we can't set a Supplier, so the new Set must bring one in
1108 0 : Reference< XNumberFormatsSupplier> xSupplier;
1109 0 : xNewProps->getPropertyValue(sPropFormatsSupplier) >>= xSupplier;
1110 0 : if (xSupplier.is())
1111 : {
1112 0 : Reference< XNumberFormats> xFormats(xSupplier->getNumberFormats());
1113 :
1114 : // Set number of decimals
1115 0 : sal_Int16 nDecimals = 2;
1116 0 : if (hasProperty(sPropDecimalAccuracy, xOldProps))
1117 0 : xOldProps->getPropertyValue(sPropDecimalAccuracy) >>= nDecimals;
1118 :
1119 : // base format (depending on the ClassId of the old Set)
1120 0 : sal_Int32 nBaseKey = 0;
1121 0 : if (hasProperty(sPropClassId, xOldProps))
1122 : {
1123 0 : Reference< XNumberFormatTypes> xTypeList(xFormats, UNO_QUERY);
1124 0 : if (xTypeList.is())
1125 : {
1126 0 : sal_Int16 nClassId = 0;
1127 0 : xOldProps->getPropertyValue(sPropClassId) >>= nClassId;
1128 0 : switch (nClassId)
1129 : {
1130 : case FormComponentType::DATEFIELD :
1131 0 : nBaseKey = xTypeList->getStandardFormat(NumberFormat::DATE, _rLocale);
1132 0 : break;
1133 :
1134 : case FormComponentType::TIMEFIELD :
1135 0 : nBaseKey = xTypeList->getStandardFormat(NumberFormat::TIME, _rLocale);
1136 0 : break;
1137 :
1138 : case FormComponentType::CURRENCYFIELD :
1139 0 : nBaseKey = xTypeList->getStandardFormat(NumberFormat::CURRENCY, _rLocale);
1140 0 : break;
1141 : }
1142 0 : }
1143 : }
1144 :
1145 : // With this we can generate a new format ...
1146 0 : OUString sNewFormat = xFormats->generateFormat(nBaseKey, _rLocale, sal_False, sal_False, nDecimals, 0);
1147 : // No thousands separator, negative numbers are not in red, no leading zeros
1148 :
1149 : // ... and add at FormatsSupplier (if needed)
1150 0 : sal_Int32 nKey = xFormats->queryKey(sNewFormat, _rLocale, sal_False);
1151 0 : if (nKey == (sal_Int32)-1)
1152 : { // not added yet in my formatter ...
1153 0 : nKey = xFormats->addNew(sNewFormat, _rLocale);
1154 : }
1155 :
1156 0 : xNewProps->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY), makeAny((sal_Int32)nKey));
1157 : }
1158 :
1159 : // min-/max-Value
1160 0 : Any aNewMin, aNewMax;
1161 0 : if (hasProperty(sPropValueMin, xOldProps))
1162 0 : aNewMin = xOldProps->getPropertyValue(sPropValueMin);
1163 0 : if (hasProperty(sPropValueMax, xOldProps))
1164 0 : aNewMax = xOldProps->getPropertyValue(sPropValueMax);
1165 0 : xNewProps->setPropertyValue(sPropEffectiveMin, aNewMin);
1166 0 : xNewProps->setPropertyValue(sPropEffectiveMax, aNewMax);
1167 :
1168 : // Default-Value
1169 0 : Any aNewDefault;
1170 0 : if (hasProperty(sPropDefaultDate, xOldProps))
1171 : {
1172 0 : Any aDate( xOldProps->getPropertyValue(sPropDefaultDate) );
1173 0 : if (aDate.hasValue())
1174 0 : aNewDefault <<= DBTypeConversion::toDouble(*(Date*)aDate.getValue());
1175 : }
1176 :
1177 0 : if (hasProperty(sPropDefaultTime, xOldProps))
1178 : {
1179 0 : Any aTime( xOldProps->getPropertyValue(sPropDefaultTime) );
1180 0 : if (aTime.hasValue())
1181 0 : aNewDefault <<= DBTypeConversion::toDouble(*(Time*)aTime.getValue());
1182 : }
1183 :
1184 : // double or OUString will be copied directly
1185 0 : if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE), xOldProps))
1186 0 : aNewDefault = xOldProps->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE));
1187 0 : if (hasProperty(sPropDefaultText, xOldProps))
1188 0 : aNewDefault = xOldProps->getPropertyValue(sPropDefaultText);
1189 :
1190 0 : if (aNewDefault.hasValue())
1191 0 : xNewProps->setPropertyValue(sPropEffectiveDefault, aNewDefault);
1192 0 : }
1193 : }
1194 0 : catch(const Exception&)
1195 : {
1196 : OSL_FAIL( "TransferFormComponentProperties: caught an exception!" );
1197 : }
1198 : }
1199 :
1200 0 : bool canInsert(const Reference< XPropertySet>& _rxCursorSet)
1201 : {
1202 0 : return ((_rxCursorSet.is() && (getINT32(_rxCursorSet->getPropertyValue("Privileges")) & Privilege::INSERT) != 0));
1203 : }
1204 :
1205 0 : bool canUpdate(const Reference< XPropertySet>& _rxCursorSet)
1206 : {
1207 0 : return ((_rxCursorSet.is() && (getINT32(_rxCursorSet->getPropertyValue("Privileges")) & Privilege::UPDATE) != 0));
1208 : }
1209 :
1210 0 : bool canDelete(const Reference< XPropertySet>& _rxCursorSet)
1211 : {
1212 0 : return ((_rxCursorSet.is() && (getINT32(_rxCursorSet->getPropertyValue("Privileges")) & Privilege::DELETE) != 0));
1213 : }
1214 :
1215 0 : Reference< XDataSource> findDataSource(const Reference< XInterface >& _xParent)
1216 : {
1217 0 : Reference< XOfficeDatabaseDocument> xDatabaseDocument(_xParent, UNO_QUERY);
1218 0 : Reference< XDataSource> xDataSource;
1219 0 : if ( xDatabaseDocument.is() )
1220 0 : xDataSource = xDatabaseDocument->getDataSource();
1221 0 : if ( !xDataSource.is() )
1222 0 : xDataSource.set(_xParent, UNO_QUERY);
1223 0 : if (!xDataSource.is())
1224 : {
1225 0 : Reference< XChild> xChild(_xParent, UNO_QUERY);
1226 0 : if ( xChild.is() )
1227 0 : xDataSource = findDataSource(xChild->getParent());
1228 : }
1229 0 : return xDataSource;
1230 : }
1231 :
1232 0 : Reference< XSingleSelectQueryComposer > getComposedRowSetStatement( const Reference< XPropertySet >& _rxRowSet, const Reference< XComponentContext >& _rxContext )
1233 : SAL_THROW( ( SQLException ) )
1234 : {
1235 0 : Reference< XSingleSelectQueryComposer > xComposer;
1236 : try
1237 : {
1238 0 : Reference< XConnection> xConn = connectRowset( Reference< XRowSet >( _rxRowSet, UNO_QUERY ), _rxContext, true );
1239 0 : if ( xConn.is() ) // implies _rxRowSet.is()
1240 : {
1241 : // build the statement the row set is based on (can't use the ActiveCommand property of the set
1242 : // as this reflects the status after the last execute, not the currently set properties)
1243 :
1244 0 : sal_Int32 nCommandType = CommandType::COMMAND;
1245 0 : OUString sCommand;
1246 0 : sal_Bool bEscapeProcessing = sal_False;
1247 :
1248 0 : OSL_VERIFY( _rxRowSet->getPropertyValue("CommandType") >>= nCommandType );
1249 0 : OSL_VERIFY( _rxRowSet->getPropertyValue("Command") >>= sCommand );
1250 0 : OSL_VERIFY( _rxRowSet->getPropertyValue("EscapeProcessing") >>= bEscapeProcessing );
1251 :
1252 0 : StatementComposer aComposer( xConn, sCommand, nCommandType, bEscapeProcessing );
1253 : // append sort
1254 0 : aComposer.setOrder( getString( _rxRowSet->getPropertyValue("Order") ) );
1255 :
1256 : // append filter
1257 0 : sal_Bool bApplyFilter = sal_True;
1258 0 : _rxRowSet->getPropertyValue("ApplyFilter") >>= bApplyFilter;
1259 0 : if ( bApplyFilter )
1260 0 : aComposer.setFilter( getString( _rxRowSet->getPropertyValue("Filter") ) );
1261 :
1262 0 : aComposer.getQuery();
1263 :
1264 0 : xComposer = aComposer.getComposer();
1265 0 : aComposer.setDisposeComposer( false );
1266 0 : }
1267 : }
1268 0 : catch( const SQLException& )
1269 : {
1270 0 : throw;
1271 : }
1272 0 : catch( const Exception& )
1273 : {
1274 : DBG_UNHANDLED_EXCEPTION();
1275 : }
1276 :
1277 0 : return xComposer;
1278 : }
1279 :
1280 0 : Reference< XSingleSelectQueryComposer > getCurrentSettingsComposer(
1281 : const Reference< XPropertySet>& _rxRowSetProps,
1282 : const Reference< XComponentContext>& _rxContext)
1283 : {
1284 0 : Reference< XSingleSelectQueryComposer > xReturn;
1285 : try
1286 : {
1287 0 : xReturn = getComposedRowSetStatement( _rxRowSetProps, _rxContext );
1288 : }
1289 0 : catch( const SQLException& )
1290 : {
1291 0 : throw;
1292 : }
1293 0 : catch( const Exception& )
1294 : {
1295 : OSL_FAIL( "::getCurrentSettingsComposer : caught an exception !" );
1296 : }
1297 :
1298 0 : return xReturn;
1299 : }
1300 :
1301 0 : OUString composeTableName( const Reference< XDatabaseMetaData >& _rxMetaData,
1302 : const OUString& _rCatalog,
1303 : const OUString& _rSchema,
1304 : const OUString& _rName,
1305 : bool _bQuote,
1306 : EComposeRule _eComposeRule)
1307 : {
1308 0 : return impl_doComposeTableName( _rxMetaData, _rCatalog, _rSchema, _rName, _bQuote, _eComposeRule );
1309 : }
1310 :
1311 0 : OUString composeTableNameForSelect( const Reference< XConnection >& _rxConnection,
1312 : const OUString& _rCatalog, const OUString& _rSchema, const OUString& _rName )
1313 : {
1314 0 : bool bUseCatalogInSelect = isDataSourcePropertyEnabled( _rxConnection, OUString( "UseCatalogInSelect" ), true );
1315 0 : bool bUseSchemaInSelect = isDataSourcePropertyEnabled( _rxConnection, OUString( "UseSchemaInSelect" ), true );
1316 :
1317 : return impl_doComposeTableName(
1318 0 : _rxConnection->getMetaData(),
1319 : bUseCatalogInSelect ? _rCatalog : OUString(),
1320 : bUseSchemaInSelect ? _rSchema : OUString(),
1321 : _rName,
1322 : true,
1323 : eInDataManipulation
1324 0 : );
1325 : }
1326 :
1327 : namespace
1328 : {
1329 0 : static void lcl_getTableNameComponents( const Reference<XPropertySet>& _xTable,
1330 : OUString& _out_rCatalog, OUString& _out_rSchema, OUString& _out_rName )
1331 : {
1332 0 : ::dbtools::OPropertyMap& rPropMap = OMetaConnection::getPropMap();
1333 0 : Reference< XPropertySetInfo > xInfo;
1334 0 : if (_xTable.is())
1335 0 : xInfo = _xTable->getPropertySetInfo();
1336 0 : if ( xInfo.is()
1337 0 : && xInfo->hasPropertyByName(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) )
1338 : {
1339 0 : if ( xInfo->hasPropertyByName(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME))
1340 0 : && xInfo->hasPropertyByName(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) )
1341 : {
1342 0 : _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_CATALOGNAME)) >>= _out_rCatalog;
1343 0 : _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_SCHEMANAME)) >>= _out_rSchema;
1344 : }
1345 0 : _xTable->getPropertyValue(rPropMap.getNameByIndex(PROPERTY_ID_NAME)) >>= _out_rName;
1346 : }
1347 : else
1348 0 : OSL_FAIL( "::dbtools::lcl_getTableNameComponents: this is no table object!" );
1349 0 : }
1350 : }
1351 :
1352 0 : OUString composeTableNameForSelect( const Reference< XConnection >& _rxConnection, const Reference<XPropertySet>& _xTable )
1353 : {
1354 0 : OUString sCatalog, sSchema, sName;
1355 0 : lcl_getTableNameComponents( _xTable, sCatalog, sSchema, sName );
1356 :
1357 0 : return composeTableNameForSelect( _rxConnection, sCatalog, sSchema, sName );
1358 : }
1359 :
1360 0 : OUString composeTableName(const Reference<XDatabaseMetaData>& _xMetaData,
1361 : const Reference<XPropertySet>& _xTable,
1362 : EComposeRule _eComposeRule,
1363 : bool _bSuppressCatalog,
1364 : bool _bSuppressSchema,
1365 : bool _bQuote )
1366 : {
1367 0 : OUString sCatalog, sSchema, sName;
1368 0 : lcl_getTableNameComponents( _xTable, sCatalog, sSchema, sName );
1369 :
1370 : return impl_doComposeTableName(
1371 : _xMetaData,
1372 : _bSuppressCatalog ? OUString() : sCatalog,
1373 : _bSuppressSchema ? OUString() : sSchema,
1374 : sName,
1375 : _bQuote,
1376 : _eComposeRule
1377 0 : );
1378 : }
1379 :
1380 0 : sal_Int32 getSearchColumnFlag( const Reference< XConnection>& _rxConn,sal_Int32 _nDataType)
1381 : {
1382 0 : sal_Int32 nSearchFlag = 0;
1383 0 : Reference<XResultSet> xSet = _rxConn->getMetaData()->getTypeInfo();
1384 0 : if(xSet.is())
1385 : {
1386 0 : Reference<XRow> xRow(xSet,UNO_QUERY);
1387 0 : while(xSet->next())
1388 : {
1389 0 : if(xRow->getInt(2) == _nDataType)
1390 : {
1391 0 : nSearchFlag = xRow->getInt(9);
1392 0 : break;
1393 : }
1394 0 : }
1395 : }
1396 0 : return nSearchFlag;
1397 : }
1398 :
1399 0 : OUString createUniqueName( const Sequence< OUString >& _rNames, const OUString& _rBaseName, bool _bStartWithNumber )
1400 : {
1401 0 : ::std::set< OUString > aUsedNames;
1402 : ::std::copy(
1403 : _rNames.getConstArray(),
1404 0 : _rNames.getConstArray() + _rNames.getLength(),
1405 : ::std::insert_iterator< ::std::set< OUString > >( aUsedNames, aUsedNames.end() )
1406 0 : );
1407 :
1408 0 : OUString sName( _rBaseName );
1409 0 : sal_Int32 nPos = 1;
1410 0 : if ( _bStartWithNumber )
1411 0 : sName += OUString::number( nPos );
1412 :
1413 0 : while ( aUsedNames.find( sName ) != aUsedNames.end() )
1414 : {
1415 0 : sName = _rBaseName;
1416 0 : sName += OUString::number( ++nPos );
1417 : }
1418 0 : return sName;
1419 : }
1420 :
1421 0 : OUString createUniqueName(const Reference<XNameAccess>& _rxContainer,const OUString& _rBaseName, bool _bStartWithNumber)
1422 : {
1423 0 : Sequence< OUString > aElementNames;
1424 :
1425 : OSL_ENSURE( _rxContainer.is(), "createUniqueName: invalid container!" );
1426 0 : if ( _rxContainer.is() )
1427 0 : aElementNames = _rxContainer->getElementNames();
1428 :
1429 0 : return createUniqueName( aElementNames, _rBaseName, _bStartWithNumber );
1430 : }
1431 :
1432 0 : void showError(const SQLExceptionInfo& _rInfo,
1433 : const Reference< XWindow>& _xParent,
1434 : const Reference< XComponentContext >& _rxContext)
1435 : {
1436 0 : if (_rInfo.isValid())
1437 : {
1438 : try
1439 : {
1440 0 : Reference< XExecutableDialog > xErrorDialog = ErrorMessageDialog::create( _rxContext, "", _xParent, _rInfo.get() );
1441 0 : xErrorDialog->execute();
1442 : }
1443 0 : catch(const Exception&)
1444 : {
1445 : OSL_FAIL("showError: could not display the error message!");
1446 : }
1447 : }
1448 0 : }
1449 :
1450 0 : bool implUpdateObject(const Reference< XRowUpdate >& _rxUpdatedObject,
1451 : const sal_Int32 _nColumnIndex, const Any& _rValue) SAL_THROW ( ( SQLException, RuntimeException ) )
1452 : {
1453 0 : bool bSuccessfullyReRouted = true;
1454 0 : switch (_rValue.getValueTypeClass())
1455 : {
1456 : case TypeClass_ANY:
1457 : {
1458 0 : Any aInnerValue;
1459 0 : _rValue >>= aInnerValue;
1460 0 : bSuccessfullyReRouted = implUpdateObject(_rxUpdatedObject, _nColumnIndex, aInnerValue);
1461 : }
1462 0 : break;
1463 :
1464 : case TypeClass_VOID:
1465 0 : _rxUpdatedObject->updateNull(_nColumnIndex);
1466 0 : break;
1467 :
1468 : case TypeClass_STRING:
1469 0 : _rxUpdatedObject->updateString(_nColumnIndex, *(OUString*)_rValue.getValue());
1470 0 : break;
1471 :
1472 : case TypeClass_BOOLEAN:
1473 0 : _rxUpdatedObject->updateBoolean(_nColumnIndex, *(sal_Bool *)_rValue.getValue());
1474 0 : break;
1475 :
1476 : case TypeClass_BYTE:
1477 0 : _rxUpdatedObject->updateByte(_nColumnIndex, *(sal_Int8 *)_rValue.getValue());
1478 0 : break;
1479 :
1480 : case TypeClass_UNSIGNED_SHORT:
1481 : case TypeClass_SHORT:
1482 0 : _rxUpdatedObject->updateShort(_nColumnIndex, *(sal_Int16*)_rValue.getValue());
1483 0 : break;
1484 :
1485 : case TypeClass_CHAR:
1486 0 : _rxUpdatedObject->updateString(_nColumnIndex,OUString((sal_Unicode *)_rValue.getValue(),1));
1487 0 : break;
1488 :
1489 : case TypeClass_UNSIGNED_LONG:
1490 : case TypeClass_LONG:
1491 0 : _rxUpdatedObject->updateInt(_nColumnIndex, *(sal_Int32*)_rValue.getValue());
1492 0 : break;
1493 :
1494 : case TypeClass_HYPER:
1495 : {
1496 0 : sal_Int64 nValue = 0;
1497 0 : OSL_VERIFY( _rValue >>= nValue );
1498 0 : _rxUpdatedObject->updateLong( _nColumnIndex, nValue );
1499 : }
1500 0 : break;
1501 :
1502 : case TypeClass_FLOAT:
1503 0 : _rxUpdatedObject->updateFloat(_nColumnIndex, *(float*)_rValue.getValue());
1504 0 : break;
1505 :
1506 : case TypeClass_DOUBLE:
1507 0 : _rxUpdatedObject->updateDouble(_nColumnIndex, *(double*)_rValue.getValue());
1508 0 : break;
1509 :
1510 : case TypeClass_SEQUENCE:
1511 0 : if (_rValue.getValueType() == ::getCppuType((const Sequence< sal_Int8 > *)0))
1512 0 : _rxUpdatedObject->updateBytes(_nColumnIndex, *(Sequence<sal_Int8>*)_rValue.getValue());
1513 : else
1514 0 : bSuccessfullyReRouted = false;
1515 0 : break;
1516 : case TypeClass_STRUCT:
1517 0 : if (_rValue.getValueType() == ::getCppuType((const DateTime*)0))
1518 0 : _rxUpdatedObject->updateTimestamp(_nColumnIndex, *(DateTime*)_rValue.getValue());
1519 0 : else if (_rValue.getValueType() == ::getCppuType((const Date*)0))
1520 0 : _rxUpdatedObject->updateDate(_nColumnIndex, *(Date*)_rValue.getValue());
1521 0 : else if (_rValue.getValueType() == ::getCppuType((const Time*)0))
1522 0 : _rxUpdatedObject->updateTime(_nColumnIndex, *(Time*)_rValue.getValue());
1523 : else
1524 0 : bSuccessfullyReRouted = false;
1525 0 : break;
1526 :
1527 : case TypeClass_INTERFACE:
1528 0 : if (_rValue.getValueType() == ::getCppuType(static_cast<Reference< XInputStream>*>(NULL)))
1529 : {
1530 0 : Reference< XInputStream > xStream;
1531 0 : _rValue >>= xStream;
1532 0 : _rxUpdatedObject->updateBinaryStream(_nColumnIndex, xStream, xStream->available());
1533 0 : break;
1534 : }
1535 : // run through
1536 : default:
1537 0 : bSuccessfullyReRouted = false;
1538 : }
1539 :
1540 0 : return bSuccessfullyReRouted;
1541 : }
1542 :
1543 0 : bool implSetObject( const Reference< XParameters >& _rxParameters,
1544 : const sal_Int32 _nColumnIndex, const Any& _rValue) SAL_THROW ( ( SQLException, RuntimeException ) )
1545 : {
1546 0 : bool bSuccessfullyReRouted = true;
1547 0 : switch (_rValue.getValueTypeClass())
1548 : {
1549 : case TypeClass_UNSIGNED_HYPER:
1550 : {
1551 0 : sal_uInt64 nValue = 0;
1552 0 : OSL_VERIFY( _rValue >>= nValue );
1553 0 : _rxParameters->setString(_nColumnIndex, OUString::number(nValue));
1554 : }
1555 0 : break;
1556 :
1557 : case TypeClass_UNSIGNED_LONG:
1558 : case TypeClass_HYPER:
1559 : {
1560 0 : sal_Int64 nValue = 0;
1561 0 : OSL_VERIFY( _rValue >>= nValue );
1562 0 : _rxParameters->setLong( _nColumnIndex, nValue );
1563 : }
1564 0 : break;
1565 :
1566 : case TypeClass_ANY:
1567 : {
1568 0 : Any aInnerValue;
1569 0 : _rValue >>= aInnerValue;
1570 0 : bSuccessfullyReRouted = implSetObject(_rxParameters, _nColumnIndex, aInnerValue);
1571 : }
1572 0 : break;
1573 :
1574 : case TypeClass_VOID:
1575 0 : _rxParameters->setNull(_nColumnIndex,DataType::VARCHAR);
1576 0 : break;
1577 :
1578 : case TypeClass_STRING:
1579 0 : _rxParameters->setString(_nColumnIndex, *(OUString*)_rValue.getValue());
1580 0 : break;
1581 :
1582 : case TypeClass_BOOLEAN:
1583 0 : _rxParameters->setBoolean(_nColumnIndex, *(sal_Bool *)_rValue.getValue());
1584 0 : break;
1585 :
1586 : case TypeClass_BYTE:
1587 0 : _rxParameters->setByte(_nColumnIndex, *(sal_Int8 *)_rValue.getValue());
1588 0 : break;
1589 :
1590 : case TypeClass_SHORT:
1591 0 : _rxParameters->setShort(_nColumnIndex, *(sal_Int16*)_rValue.getValue());
1592 0 : break;
1593 :
1594 : case TypeClass_CHAR:
1595 0 : _rxParameters->setString(_nColumnIndex, OUString((sal_Unicode *)_rValue.getValue(),1));
1596 0 : break;
1597 :
1598 : case TypeClass_UNSIGNED_SHORT:
1599 : case TypeClass_LONG:
1600 : {
1601 0 : sal_Int32 nValue = 0;
1602 0 : OSL_VERIFY( _rValue >>= nValue );
1603 0 : _rxParameters->setInt(_nColumnIndex, nValue);
1604 0 : break;
1605 : }
1606 :
1607 : case TypeClass_FLOAT:
1608 0 : _rxParameters->setFloat(_nColumnIndex, *(float*)_rValue.getValue());
1609 0 : break;
1610 :
1611 : case TypeClass_DOUBLE:
1612 0 : _rxParameters->setDouble(_nColumnIndex, *(double*)_rValue.getValue());
1613 0 : break;
1614 :
1615 : case TypeClass_SEQUENCE:
1616 0 : if (_rValue.getValueType() == ::getCppuType((const Sequence< sal_Int8 > *)0))
1617 : {
1618 0 : _rxParameters->setBytes(_nColumnIndex, *(Sequence<sal_Int8>*)_rValue.getValue());
1619 : }
1620 : else
1621 0 : bSuccessfullyReRouted = false;
1622 0 : break;
1623 : case TypeClass_STRUCT:
1624 0 : if (_rValue.getValueType() == ::getCppuType((const DateTime*)0))
1625 0 : _rxParameters->setTimestamp(_nColumnIndex, *(DateTime*)_rValue.getValue());
1626 0 : else if (_rValue.getValueType() == ::getCppuType((const Date*)0))
1627 0 : _rxParameters->setDate(_nColumnIndex, *(Date*)_rValue.getValue());
1628 0 : else if (_rValue.getValueType() == ::getCppuType((const Time*)0))
1629 0 : _rxParameters->setTime(_nColumnIndex, *(Time*)_rValue.getValue());
1630 : else
1631 0 : bSuccessfullyReRouted = false;
1632 0 : break;
1633 :
1634 : case TypeClass_INTERFACE:
1635 0 : if (_rValue.getValueType() == ::getCppuType(static_cast<Reference< XInputStream>*>(NULL)))
1636 : {
1637 0 : Reference< XInputStream > xStream;
1638 0 : _rValue >>= xStream;
1639 0 : _rxParameters->setBinaryStream(_nColumnIndex, xStream, xStream->available());
1640 0 : break;
1641 : }
1642 : // run through
1643 : default:
1644 0 : bSuccessfullyReRouted = false;
1645 :
1646 : }
1647 :
1648 0 : return bSuccessfullyReRouted;
1649 : }
1650 :
1651 : namespace
1652 : {
1653 0 : class OParameterWrapper : public ::cppu::WeakImplHelper1< XIndexAccess >
1654 : {
1655 : ::std::vector<bool, std::allocator<bool> > m_aSet;
1656 : Reference<XIndexAccess> m_xSource;
1657 : public:
1658 0 : OParameterWrapper(const ::std::vector<bool, std::allocator<bool> >& _aSet,const Reference<XIndexAccess>& _xSource) : m_aSet(_aSet),m_xSource(_xSource){}
1659 : private:
1660 : // ::com::sun::star::container::XElementAccess
1661 0 : virtual Type SAL_CALL getElementType() throw(RuntimeException, std::exception) SAL_OVERRIDE
1662 : {
1663 0 : return m_xSource->getElementType();
1664 : }
1665 0 : virtual sal_Bool SAL_CALL hasElements( ) throw(RuntimeException, std::exception) SAL_OVERRIDE
1666 : {
1667 0 : if ( m_aSet.empty() )
1668 0 : return m_xSource->hasElements();
1669 0 : return ::std::count(m_aSet.begin(),m_aSet.end(),false) != 0;
1670 : }
1671 : // ::com::sun::star::container::XIndexAccess
1672 0 : virtual sal_Int32 SAL_CALL getCount( ) throw(RuntimeException, std::exception) SAL_OVERRIDE
1673 : {
1674 0 : if ( m_aSet.empty() )
1675 0 : return m_xSource->getCount();
1676 0 : return ::std::count(m_aSet.begin(),m_aSet.end(),false);
1677 : }
1678 0 : virtual Any SAL_CALL getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception) SAL_OVERRIDE
1679 : {
1680 0 : if ( m_aSet.empty() )
1681 0 : return m_xSource->getByIndex(Index);
1682 0 : if ( m_aSet.size() < (size_t)Index )
1683 0 : throw IndexOutOfBoundsException();
1684 :
1685 0 : ::std::vector<bool, std::allocator<bool> >::iterator aIter = m_aSet.begin();
1686 0 : ::std::vector<bool, std::allocator<bool> >::iterator aEnd = m_aSet.end();
1687 0 : sal_Int32 i = 0;
1688 0 : sal_Int32 nParamPos = -1;
1689 0 : for(; aIter != aEnd && i <= Index; ++aIter)
1690 : {
1691 0 : ++nParamPos;
1692 0 : if ( !*aIter )
1693 : {
1694 0 : ++i;
1695 : }
1696 : }
1697 0 : return m_xSource->getByIndex(nParamPos);
1698 : }
1699 : };
1700 : }
1701 :
1702 0 : void askForParameters(const Reference< XSingleSelectQueryComposer >& _xComposer,
1703 : const Reference<XParameters>& _xParameters,
1704 : const Reference< XConnection>& _xConnection,
1705 : const Reference< XInteractionHandler >& _rxHandler,
1706 : const ::std::vector<bool, std::allocator<bool> >& _aParametersSet)
1707 : {
1708 : OSL_ENSURE(_xComposer.is(),"dbtools::askForParameters XSQLQueryComposer is null!");
1709 : OSL_ENSURE(_xParameters.is(),"dbtools::askForParameters XParameters is null!");
1710 : OSL_ENSURE(_xConnection.is(),"dbtools::askForParameters XConnection is null!");
1711 : OSL_ENSURE(_rxHandler.is(),"dbtools::askForParameters XInteractionHandler is null!");
1712 :
1713 : // we have to set this here again because getCurrentSettingsComposer can force a setpropertyvalue
1714 0 : Reference<XParametersSupplier> xParameters = Reference<XParametersSupplier> (_xComposer, UNO_QUERY);
1715 :
1716 0 : Reference<XIndexAccess> xParamsAsIndicies = xParameters.is() ? xParameters->getParameters() : Reference<XIndexAccess>();
1717 0 : sal_Int32 nParamCount = xParamsAsIndicies.is() ? xParamsAsIndicies->getCount() : 0;
1718 0 : ::std::vector<bool, std::allocator<bool> > aNewParameterSet( _aParametersSet );
1719 0 : if ( nParamCount && ::std::count(aNewParameterSet.begin(),aNewParameterSet.end(),true) != nParamCount )
1720 : {
1721 0 : static const OUString PROPERTY_NAME(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME));
1722 0 : aNewParameterSet.resize(nParamCount ,false);
1723 : typedef ::std::map< OUString, ::std::vector<sal_Int32> > TParameterPositions;
1724 0 : TParameterPositions aParameterNames;
1725 0 : for(sal_Int32 i = 0; i < nParamCount; ++i)
1726 : {
1727 0 : Reference<XPropertySet> xParam(xParamsAsIndicies->getByIndex(i),UNO_QUERY);
1728 0 : OUString sName;
1729 0 : xParam->getPropertyValue(PROPERTY_NAME) >>= sName;
1730 :
1731 0 : TParameterPositions::iterator aFind = aParameterNames.find(sName);
1732 0 : if ( aFind != aParameterNames.end() )
1733 0 : aNewParameterSet[i] = true;
1734 0 : aParameterNames[sName].push_back(i+1);
1735 0 : }
1736 : // build an interaction request
1737 : // two continuations (Ok and Cancel)
1738 0 : OInteractionAbort* pAbort = new OInteractionAbort;
1739 0 : OParameterContinuation* pParams = new OParameterContinuation;
1740 : // the request
1741 0 : ParametersRequest aRequest;
1742 0 : Reference<XIndexAccess> xWrappedParameters = new OParameterWrapper(aNewParameterSet,xParamsAsIndicies);
1743 0 : aRequest.Parameters = xWrappedParameters;
1744 0 : aRequest.Connection = _xConnection;
1745 0 : OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest));
1746 0 : Reference< XInteractionRequest > xRequest(pRequest);
1747 : // some knittings
1748 0 : pRequest->addContinuation(pAbort);
1749 0 : pRequest->addContinuation(pParams);
1750 :
1751 : // execute the request
1752 0 : _rxHandler->handle(xRequest);
1753 :
1754 0 : if (!pParams->wasSelected())
1755 : {
1756 : // canceled by the user (i.e. (s)he canceled the dialog)
1757 0 : RowSetVetoException e;
1758 0 : e.ErrorCode = ParameterInteractionCancelled;
1759 0 : throw e;
1760 : }
1761 :
1762 : // now transfer the values from the continuation object to the parameter columns
1763 0 : Sequence< PropertyValue > aFinalValues = pParams->getValues();
1764 0 : const PropertyValue* pFinalValues = aFinalValues.getConstArray();
1765 0 : for (sal_Int32 i=0; i<aFinalValues.getLength(); ++i, ++pFinalValues)
1766 : {
1767 0 : Reference< XPropertySet > xParamColumn(xWrappedParameters->getByIndex(i),UNO_QUERY);
1768 0 : if (xParamColumn.is())
1769 : {
1770 0 : OUString sName;
1771 0 : xParamColumn->getPropertyValue(PROPERTY_NAME) >>= sName;
1772 : OSL_ENSURE(sName.equals(pFinalValues->Name), "::dbaui::askForParameters: inconsistent parameter names!");
1773 :
1774 : // determine the field type and ...
1775 0 : sal_Int32 nParamType = 0;
1776 0 : xParamColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nParamType;
1777 : // ... the scale of the parameter column
1778 0 : sal_Int32 nScale = 0;
1779 0 : if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE), xParamColumn))
1780 0 : xParamColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE)) >>= nScale;
1781 : // (the index of the parameters is one-based)
1782 0 : TParameterPositions::iterator aFind = aParameterNames.find(pFinalValues->Name);
1783 0 : ::std::vector<sal_Int32>::iterator aIterPos = aFind->second.begin();
1784 0 : ::std::vector<sal_Int32>::iterator aEndPos = aFind->second.end();
1785 0 : for(;aIterPos != aEndPos;++aIterPos)
1786 : {
1787 0 : if ( _aParametersSet.empty() || !_aParametersSet[(*aIterPos)-1] )
1788 : {
1789 0 : _xParameters->setObjectWithInfo(*aIterPos, pFinalValues->Value, nParamType, nScale);
1790 : }
1791 0 : }
1792 : }
1793 0 : }
1794 0 : }
1795 0 : }
1796 :
1797 0 : void setObjectWithInfo(const Reference<XParameters>& _xParams,
1798 : sal_Int32 parameterIndex,
1799 : const Any& x,
1800 : sal_Int32 sqlType,
1801 : sal_Int32 scale) throw(SQLException, RuntimeException)
1802 : {
1803 0 : ORowSetValue aVal;
1804 0 : aVal.fill(x);
1805 0 : setObjectWithInfo(_xParams,parameterIndex,aVal,sqlType,scale);
1806 0 : }
1807 :
1808 0 : void setObjectWithInfo(const Reference<XParameters>& _xParams,
1809 : sal_Int32 parameterIndex,
1810 : const ::connectivity::ORowSetValue& _rValue,
1811 : sal_Int32 sqlType,
1812 : sal_Int32 scale) throw(SQLException, RuntimeException)
1813 : {
1814 0 : if ( _rValue.isNull() )
1815 0 : _xParams->setNull(parameterIndex,sqlType);
1816 : else
1817 : {
1818 0 : switch(sqlType)
1819 : {
1820 : case DataType::DECIMAL:
1821 : case DataType::NUMERIC:
1822 0 : _xParams->setObjectWithInfo(parameterIndex,_rValue.makeAny(),sqlType,scale);
1823 0 : break;
1824 : case DataType::CHAR:
1825 : case DataType::VARCHAR:
1826 : case DataType::LONGVARCHAR:
1827 0 : _xParams->setString(parameterIndex,_rValue);
1828 0 : break;
1829 : case DataType::CLOB:
1830 : {
1831 0 : Any x(_rValue.makeAny());
1832 0 : OUString sValue;
1833 0 : if ( x >>= sValue )
1834 0 : _xParams->setString(parameterIndex,sValue);
1835 : else
1836 : {
1837 0 : Reference< XClob > xClob;
1838 0 : if(x >>= xClob)
1839 0 : _xParams->setClob(parameterIndex,xClob);
1840 : else
1841 : {
1842 0 : Reference< ::com::sun::star::io::XInputStream > xStream;
1843 0 : if(x >>= xStream)
1844 0 : _xParams->setCharacterStream(parameterIndex,xStream,xStream->available());
1845 0 : }
1846 0 : }
1847 : }
1848 0 : break;
1849 : case DataType::BIGINT:
1850 0 : if ( _rValue.isSigned() )
1851 0 : _xParams->setLong(parameterIndex,_rValue);
1852 : else
1853 0 : _xParams->setString(parameterIndex,_rValue);
1854 0 : break;
1855 :
1856 : case DataType::FLOAT:
1857 0 : _xParams->setFloat(parameterIndex,_rValue);
1858 0 : break;
1859 : case DataType::REAL:
1860 : case DataType::DOUBLE:
1861 0 : _xParams->setDouble(parameterIndex,_rValue);
1862 0 : break;
1863 : case DataType::DATE:
1864 0 : _xParams->setDate(parameterIndex,_rValue);
1865 0 : break;
1866 : case DataType::TIME:
1867 0 : _xParams->setTime(parameterIndex,_rValue);
1868 0 : break;
1869 : case DataType::TIMESTAMP:
1870 0 : _xParams->setTimestamp(parameterIndex,_rValue);
1871 0 : break;
1872 : case DataType::BINARY:
1873 : case DataType::VARBINARY:
1874 : case DataType::LONGVARBINARY:
1875 : case DataType::BLOB:
1876 : {
1877 0 : Any x(_rValue.makeAny());
1878 0 : Sequence< sal_Int8> aBytes;
1879 0 : if(x >>= aBytes)
1880 0 : _xParams->setBytes(parameterIndex,aBytes);
1881 : else
1882 : {
1883 0 : Reference< XBlob > xBlob;
1884 0 : if(x >>= xBlob)
1885 0 : _xParams->setBlob(parameterIndex,xBlob);
1886 : else
1887 : {
1888 0 : Reference< XClob > xClob;
1889 0 : if(x >>= xClob)
1890 0 : _xParams->setClob(parameterIndex,xClob);
1891 : else
1892 : {
1893 0 : Reference< ::com::sun::star::io::XInputStream > xBinStream;
1894 0 : if(x >>= xBinStream)
1895 0 : _xParams->setBinaryStream(parameterIndex,xBinStream,xBinStream->available());
1896 0 : }
1897 0 : }
1898 0 : }
1899 : }
1900 0 : break;
1901 : case DataType::BIT:
1902 : case DataType::BOOLEAN:
1903 0 : _xParams->setBoolean(parameterIndex,static_cast<bool>(_rValue));
1904 0 : break;
1905 : case DataType::TINYINT:
1906 0 : if ( _rValue.isSigned() )
1907 0 : _xParams->setByte(parameterIndex,_rValue);
1908 : else
1909 0 : _xParams->setShort(parameterIndex,_rValue);
1910 0 : break;
1911 : case DataType::SMALLINT:
1912 0 : if ( _rValue.isSigned() )
1913 0 : _xParams->setShort(parameterIndex,_rValue);
1914 : else
1915 0 : _xParams->setInt(parameterIndex,_rValue);
1916 0 : break;
1917 : case DataType::INTEGER:
1918 0 : if ( _rValue.isSigned() )
1919 0 : _xParams->setInt(parameterIndex,_rValue);
1920 : else
1921 0 : _xParams->setLong(parameterIndex,_rValue);
1922 0 : break;
1923 : default:
1924 : {
1925 0 : ::connectivity::SharedResources aResources;
1926 : const OUString sError( aResources.getResourceStringWithSubstitution(
1927 : STR_UNKNOWN_PARA_TYPE,
1928 : "$position$", OUString::number(parameterIndex)
1929 0 : ) );
1930 0 : ::dbtools::throwGenericSQLException(sError,NULL);
1931 : }
1932 : }
1933 : }
1934 0 : }
1935 :
1936 0 : void getBooleanComparisonPredicate( const OUString& _rExpression, const bool _bValue, const sal_Int32 _nBooleanComparisonMode,
1937 : OUStringBuffer& _out_rSQLPredicate )
1938 : {
1939 0 : switch ( _nBooleanComparisonMode )
1940 : {
1941 : case BooleanComparisonMode::IS_LITERAL:
1942 0 : _out_rSQLPredicate.append( _rExpression );
1943 0 : if ( _bValue )
1944 0 : _out_rSQLPredicate.appendAscii( " IS TRUE" );
1945 : else
1946 0 : _out_rSQLPredicate.appendAscii( " IS FALSE" );
1947 0 : break;
1948 :
1949 : case BooleanComparisonMode::EQUAL_LITERAL:
1950 0 : _out_rSQLPredicate.append( _rExpression );
1951 0 : _out_rSQLPredicate.appendAscii( _bValue ? " = TRUE" : " = FALSE" );
1952 0 : break;
1953 :
1954 : case BooleanComparisonMode::ACCESS_COMPAT:
1955 0 : if ( _bValue )
1956 : {
1957 0 : _out_rSQLPredicate.appendAscii( " NOT ( ( " );
1958 0 : _out_rSQLPredicate.append( _rExpression );
1959 0 : _out_rSQLPredicate.appendAscii( " = 0 ) OR ( " );
1960 0 : _out_rSQLPredicate.append( _rExpression );
1961 0 : _out_rSQLPredicate.appendAscii( " IS NULL ) )" );
1962 : }
1963 : else
1964 : {
1965 0 : _out_rSQLPredicate.append( _rExpression );
1966 0 : _out_rSQLPredicate.appendAscii( " = 0" );
1967 : }
1968 0 : break;
1969 :
1970 : case BooleanComparisonMode::EQUAL_INTEGER:
1971 : // fall through
1972 : default:
1973 0 : _out_rSQLPredicate.append( _rExpression );
1974 0 : _out_rSQLPredicate.appendAscii( _bValue ? " = 1" : " = 0" );
1975 0 : break;
1976 : }
1977 0 : }
1978 :
1979 : } // namespace dbtools
1980 :
1981 : namespace connectivity
1982 : {
1983 0 : void release(oslInterlockedCount& _refCount,
1984 : ::cppu::OBroadcastHelper& rBHelper,
1985 : Reference< XInterface >& _xInterface,
1986 : ::com::sun::star::lang::XComponent* _pObject)
1987 : {
1988 0 : if (osl_atomic_decrement( &_refCount ) == 0)
1989 : {
1990 0 : osl_atomic_increment( &_refCount );
1991 :
1992 0 : if (!rBHelper.bDisposed && !rBHelper.bInDispose)
1993 : {
1994 : // remember the parent
1995 0 : Reference< XInterface > xParent;
1996 : {
1997 0 : ::osl::MutexGuard aGuard( rBHelper.rMutex );
1998 0 : xParent = _xInterface;
1999 0 : _xInterface = NULL;
2000 : }
2001 :
2002 : // First dispose
2003 0 : _pObject->dispose();
2004 :
2005 : // only the alive ref holds the object
2006 : OSL_ASSERT( _refCount == 1 );
2007 :
2008 : // release the parent in the ~
2009 0 : if (xParent.is())
2010 : {
2011 0 : ::osl::MutexGuard aGuard( rBHelper.rMutex );
2012 0 : _xInterface = xParent;
2013 0 : }
2014 : }
2015 : }
2016 : else
2017 0 : osl_atomic_increment( &_refCount );
2018 0 : }
2019 :
2020 0 : void checkDisposed(bool _bThrow) throw ( DisposedException )
2021 : {
2022 0 : if (_bThrow)
2023 0 : throw DisposedException();
2024 :
2025 0 : }
2026 :
2027 0 : OSQLColumns::Vector::const_iterator find(OSQLColumns::Vector::const_iterator __first,
2028 : OSQLColumns::Vector::const_iterator __last,
2029 : const OUString& _rVal,
2030 : const ::comphelper::UStringMixEqual& _rCase)
2031 : {
2032 0 : OUString sName = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME);
2033 0 : return find(__first,__last,sName,_rVal,_rCase);
2034 : }
2035 :
2036 0 : OSQLColumns::Vector::const_iterator findRealName(OSQLColumns::Vector::const_iterator __first,
2037 : OSQLColumns::Vector::const_iterator __last,
2038 : const OUString& _rVal,
2039 : const ::comphelper::UStringMixEqual& _rCase)
2040 : {
2041 0 : OUString sRealName = OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME);
2042 0 : return find(__first,__last,sRealName,_rVal,_rCase);
2043 : }
2044 :
2045 0 : OSQLColumns::Vector::const_iterator find(OSQLColumns::Vector::const_iterator __first,
2046 : OSQLColumns::Vector::const_iterator __last,
2047 : const OUString& _rProp,
2048 : const OUString& _rVal,
2049 : const ::comphelper::UStringMixEqual& _rCase)
2050 : {
2051 0 : while (__first != __last && !_rCase(getString((*__first)->getPropertyValue(_rProp)),_rVal))
2052 0 : ++__first;
2053 0 : return __first;
2054 : }
2055 : } //namespace connectivity
2056 :
2057 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|