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