/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
sal_Int32 nFormat = 0;
sal_Int32 nNumberType = _bIsCurrency ? NumberFormat::CURRENCY : NumberFormat::NUMBER; switch (_nDataType)
{ case DataType::BIT: case DataType::BOOLEAN:
nFormat = _xTypes->getStandardFormat(NumberFormat::LOGICAL, _rLocale); break; case DataType::TINYINT: case DataType::SMALLINT: case DataType::INTEGER: case DataType::BIGINT: case DataType::FLOAT: case DataType::REAL: case DataType::DOUBLE: case DataType::NUMERIC: case DataType::DECIMAL:
{ try
{
nFormat = _xTypes->getStandardFormat(static_cast<sal_Int16>(nNumberType), _rLocale); if(_nScale > 0)
{ // generate a new format if necessary
Reference< XNumberFormats > xFormats(_xTypes, UNO_QUERY);
OUString sNewFormat = xFormats->generateFormat( 0, _rLocale, false, false, static_cast<sal_Int16>(_nScale), 1);
// and add it to the formatter if necessary
nFormat = xFormats->queryKey(sNewFormat, _rLocale, false); if (nFormat == sal_Int32(-1))
nFormat = xFormats->addNew(sNewFormat, _rLocale);
}
} catch (Exception&)
{
nFormat = _xTypes->getStandardFormat(static_cast<sal_Int16>(nNumberType), _rLocale);
}
} break; case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: case DataType::CLOB:
nFormat = _xTypes->getStandardFormat(NumberFormat::TEXT, _rLocale); break; case DataType::DATE:
nFormat = _xTypes->getStandardFormat(NumberFormat::DATE, _rLocale); break; case DataType::TIME:
nFormat = _xTypes->getStandardFormat(NumberFormat::TIME, _rLocale); break; case DataType::TIMESTAMP:
nFormat = _xTypes->getStandardFormat(NumberFormat::DATETIME, _rLocale); break; case DataType::BINARY: case DataType::VARBINARY: case DataType::LONGVARBINARY: case DataType::SQLNULL: case DataType::OTHER: case DataType::OBJECT: case DataType::DISTINCT: case DataType::STRUCT: case DataType::ARRAY: case DataType::BLOB: case DataType::REF: default:
nFormat = _xTypes->getStandardFormat(NumberFormat::UNDEFINED, _rLocale);
} return nFormat;
}
//set ParentWindow for dialog, but just for the duration of this //call, undo at end of scope
Reference<XInitialization> xIni(xDataSource, UNO_QUERY); if (xIni.is())
{
Sequence< Any > aArgs{ Any(NamedValue( u"ParentWindow"_ustr, Any(_rxParent) )) };
xIni->initialize(aArgs);
}
// do it with interaction handler if(_rsUser.isEmpty() || _rsPwd.isEmpty())
{
Reference<XPropertySet> xProp(xDataSource,UNO_QUERY);
OUString sPwd, sUser; bool bPwdReq = false; try
{
xProp->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD)) >>= sPwd;
bPwdReq = ::cppu::any2bool(xProp->getPropertyValue(u"IsPasswordRequired"_ustr));
xProp->getPropertyValue(u"User"_ustr) >>= sUser;
} catch(Exception&)
{
OSL_FAIL("dbtools::getConnection: error while retrieving data source properties!");
} if(bPwdReq && sPwd.isEmpty())
{ // password required, but empty -> connect using an interaction handler
Reference<XCompletedConnection> xConnectionCompletion(xProp, UNO_QUERY); if (xConnectionCompletion.is())
{ // instantiate the default SDB interaction handler
Reference< XInteractionHandler > xHandler =
InteractionHandler::createWithParent(_rxContext, _rxParent);
xConnection = xConnectionCompletion->connectWithCompletion(xHandler);
}
} else
xConnection = xDataSource->getConnection(sUser, sPwd);
} if(!xConnection.is()) // try to get one if not already have one, just to make sure
xConnection = xDataSource->getConnection(_rsUser, _rsPwd);
if (xIni.is())
{
Sequence< Any > aArgs{ Any(NamedValue( u"ParentWindow"_ustr, Any(Reference<XWindow>()) )) };
xIni->initialize(aArgs);
}
// helper function which allows to implement both the connectRowset and the ensureRowSetConnection semantics // if connectRowset (which is deprecated) is removed, this function and one of its parameters are // not needed anymore, the whole implementation can be moved into ensureRowSetConnection then) static SharedConnection lcl_connectRowSet(const Reference< XRowSet>& _rxRowSet, const Reference< XComponentContext >& _rxContext, bool _bAttachAutoDisposer, const Reference< XWindow >& _rxParent)
{
SharedConnection xConnection;
do
{
Reference< XPropertySet> xRowSetProps(_rxRowSet, UNO_QUERY); if ( !xRowSetProps.is() ) break;
if ( xExistingConn.is() // 2. embedded in a database?
|| isEmbeddedInDatabase( _rxRowSet, xExistingConn ) // 3. is there a connection in the parent hierarchy?
|| ( xExistingConn = findConnection( _rxRowSet ) ).is()
)
{
xRowSetProps->setPropertyValue(u"ActiveConnection"_ustr, Any( xExistingConn ) ); // no auto disposer needed, since we did not create the connection
Reference< XConnection > xPureConnection; if (!sDataSourceName.isEmpty())
{ // the row set's data source property is set // -> try to connect, get user and pwd setting for that
OUString sUser, sPwd;
if (hasProperty(sUserProp, xRowSetProps))
xRowSetProps->getPropertyValue(sUserProp) >>= sUser; if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD), xRowSetProps))
xRowSetProps->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD)) >>= sPwd;
xPureConnection = getConnection_allowException( sDataSourceName, sUser, sPwd, _rxContext, _rxParent );
} elseif (!sURL.isEmpty())
{ // the row set has no data source, but a connection url set // -> try to connection with that url
Reference< XConnectionPool > xDriverManager; try {
xDriverManager = ConnectionPool::create( _rxContext );
} catch( const Exception& ) { } if (xDriverManager.is())
{
OUString sUser, sPwd; if (hasProperty(sUserProp, xRowSetProps))
xRowSetProps->getPropertyValue(sUserProp) >>= sUser; if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD), xRowSetProps))
xRowSetProps->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD)) >>= sPwd; if (!sUser.isEmpty())
{ // use user and pwd together with the url auto aInfo(::comphelper::InitPropertySequence({
{ "user", Any(sUser) },
{ "password", Any(sPwd) }
}));
xPureConnection = xDriverManager->getConnectionWithInfo( sURL, aInfo );
} else // just use the url
xPureConnection = xDriverManager->getConnection( sURL );
}
}
xConnection.reset(
xPureConnection,
_bAttachAutoDisposer ? SharedConnection::NoTakeOwnership : SharedConnection::TakeOwnership /* take ownership if and only if we're *not* going to auto-dispose the connection */
);
// now if we created a connection, forward it to the row set if ( xConnection.is() )
{ try
{ if ( _bAttachAutoDisposer )
{ new OAutoConnectionDisposer( _rxRowSet, xConnection );
} else
xRowSetProps->setPropertyValue(
u"ActiveConnection"_ustr,
Any( xConnection.getTyped() )
);
} catch(Exception&)
{
TOOLS_WARN_EXCEPTION( "connectivity.commontools", "EXception when we set the new active connection!");
}
}
} while ( false );
// reset the error if ( _pErrorInfo )
*_pErrorInfo = SQLExceptionInfo(); // reset the ownership holder
_rxKeepFieldsAlive.clear();
// go for the fields try
{ // some kind of state machine to ease the sharing of code
FieldLookupState eState = FAILED; switch ( _nCommandType )
{ case CommandType::TABLE:
eState = HANDLE_TABLE; break; case CommandType::QUERY:
eState = HANDLE_QUERY; break; case CommandType::COMMAND:
eState = HANDLE_SQL; break;
}
// needed in various states:
Reference< XNameAccess > xObjectCollection;
Reference< XColumnsSupplier > xSupplyColumns;
// go! while ( ( DONE != eState ) && ( FAILED != eState ) )
{ switch ( eState )
{ case HANDLE_TABLE:
{ // initial state for handling the tables
// get the table objects
Reference< XTablesSupplier > xSupplyTables( _rxConnection, UNO_QUERY ); if ( xSupplyTables.is() )
xObjectCollection = xSupplyTables->getTables(); // if something went wrong 'til here, then this will be handled in the next state
// next state: get the object
eState = RETRIEVE_OBJECT;
} break;
case HANDLE_QUERY:
{ // initial state for handling the tables
// get the table objects
Reference< XQueriesSupplier > xSupplyQueries( _rxConnection, UNO_QUERY ); if ( xSupplyQueries.is() )
xObjectCollection = xSupplyQueries->getQueries(); // if something went wrong 'til here, then this will be handled in the next state
// next state: get the object
eState = RETRIEVE_OBJECT;
} break;
case RETRIEVE_OBJECT: // here we should have an object (aka query or table) collection, and are going // to retrieve the desired object
// next state: default to FAILED
eState = FAILED;
OSL_ENSURE( xObjectCollection.is(), "::dbtools::getFieldsByCommandDescriptor: invalid connection (no sdb.Connection, or no Tables-/QueriesSupplier)!"); if ( xObjectCollection.is() && xObjectCollection->hasByName( _rCommand ) )
{
xObjectCollection->getByName( _rCommand ) >>= xSupplyColumns; // (xSupplyColumns being NULL will be handled in the next state)
// next: go for the columns
eState = RETRIEVE_COLUMNS;
} break;
case RETRIEVE_COLUMNS:
OSL_ENSURE( xSupplyColumns.is(), "::dbtools::getFieldsByCommandDescriptor: could not retrieve the columns supplier!" );
// next state: default to FAILED
eState = FAILED;
if ( xSupplyColumns.is() )
{
xFields = xSupplyColumns->getColumns(); // that's it
eState = DONE;
} break;
case HANDLE_SQL:
{
OUString sStatementToExecute( _rCommand );
// well, the main problem here is to handle statements which contain a parameter // If we would simply execute a parametrized statement, then this will fail because // we cannot supply any parameter values. // Thus, we try to analyze the statement, and to append a WHERE 0=1 filter criterion // This should cause every driver to not really execute the statement, but to return // an empty result set with the proper structure. We then can use this result set // to retrieve the columns.
if ( xComposerFac.is() )
{
Reference< XSingleSelectQueryComposer > xComposer(xComposerFac->createInstance(u"com.sun.star.sdb.SingleSelectQueryComposer"_ustr),UNO_QUERY); if ( xComposer.is() )
{
xComposer->setQuery( sStatementToExecute );
// Now set the filter to a dummy restriction which will result in an empty // result set.
xComposer->setFilter( u"0=1"_ustr );
sStatementToExecute = xComposer->getQuery( );
}
}
} catch( const Exception& )
{ // silent this error, this was just a try. If we're here, we did not change sStatementToExecute, // so it will still be _rCommand, which then will be executed without being touched
}
// now execute
Reference< XPreparedStatement > xStatement = _rxConnection->prepareStatement( sStatementToExecute ); // transfer ownership of this temporary object to the caller
_rxKeepFieldsAlive.set(xStatement, css::uno::UNO_QUERY);
// set the "MaxRows" to 0. This is just in case our attempt to append a 0=1 filter // failed - in this case, the MaxRows restriction should at least ensure that there // is no data returned (which would be potentially expensive)
Reference< XPropertySet > xStatementProps( xStatement,UNO_QUERY ); try
{ if ( xStatementProps.is() )
xStatementProps->setPropertyValue( u"MaxRows"_ustr, Any( sal_Int32( 0 ) ) );
} catch( const Exception& )
{
OSL_FAIL( "::dbtools::getFieldsByCommandDescriptor: could not set the MaxRows!" ); // oh damn. Not much of a chance to recover, we will no retrieve the complete // full blown result set
}
xSupplyColumns.set(xStatement->executeQuery(), css::uno::UNO_QUERY); // this should have given us a result set which does not contain any data, but // the structural information we need
// so the next state is to get the columns
eState = RETRIEVE_COLUMNS;
} break;
default:
OSL_FAIL( "::dbtools::getFieldsByCommandDescriptor: oops! unhandled state here!" );
eState = FAILED;
}
}
} catch( const SQLContext& e ) { if ( _pErrorInfo ) *_pErrorInfo = SQLExceptionInfo( e ); } catch( const SQLWarning& e ) { if ( _pErrorInfo ) *_pErrorInfo = SQLExceptionInfo( e ); } catch( const SQLException& e ) { if ( _pErrorInfo ) *_pErrorInfo = SQLExceptionInfo( e ); } catch( const Exception& )
{
TOOLS_WARN_EXCEPTION( "connectivity.commontools", "::dbtools::getFieldsByCommandDescriptor: caught an exception while retrieving the fields!" );
}
OUString sName(_rQualifiedName); // do we have catalogs? if ( aNameComps.bCatalogs )
{ if (_rxConnMetaData->isCatalogAtStart())
{ // search for the catalog name at the beginning
sal_Int32 nIndex = sName.indexOf(sSeparator); if (-1 != nIndex)
{
_rCatalog = sName.copy(0, nIndex);
sName = sName.copy(nIndex + 1);
}
} else
{ // Catalog name at the end
sal_Int32 nIndex = sName.lastIndexOf(sSeparator); if (-1 != nIndex)
{
_rCatalog = sName.copy(nIndex + 1);
sName = sName.copy(0, nIndex);
}
}
}
// First we copy all the Props, that are available in source and target and have the same description
Reference< XPropertySetInfo> xOldInfo( xOldProps->getPropertySetInfo());
Reference< XPropertySetInfo> xNewInfo( xNewProps->getPropertySetInfo());
if ( ( pResult != aNewProperties.end() )
&& ( pResult->Name == rOldProp.Name )
&& ( (pResult->Attributes & PropertyAttribute::READONLY) == 0 )
&& ( pResult->Type.equals(rOldProp.Type)) )
{ // Attributes match and the property is not read-only try
{
xNewProps->setPropertyValue(pResult->Name, xOldProps->getPropertyValue(pResult->Name));
} catch(IllegalArgumentException const &)
{
TOOLS_WARN_EXCEPTION( "connectivity.commontools", "TransferFormComponentProperties : could not transfer the value for property \""
<< pResult->Name << "\"");
}
}
}
}
// for formatted fields (either old or new) we have some special treatments
Reference< XServiceInfo > xSI( xOldProps, UNO_QUERY ); bool bOldIsFormatted = xSI.is() && xSI->supportsService( sFormattedServiceName );
xSI.set( xNewProps, UNO_QUERY ); bool bNewIsFormatted = xSI.is() && xSI->supportsService( sFormattedServiceName );
if (!bOldIsFormatted && !bNewIsFormatted) return; // nothing to do
if (bOldIsFormatted && bNewIsFormatted) // if both fields are formatted we do no conversions return;
if (bOldIsFormatted)
{ // get some properties from the selected format and put them in the new Set
Any aFormatKey( xOldProps->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY)) ); if (aFormatKey.hasValue())
{
Reference< XNumberFormatsSupplier> xSupplier;
xOldProps->getPropertyValue(sPropFormatsSupplier) >>= xSupplier; if (xSupplier.is())
{
Reference< XNumberFormats> xFormats(xSupplier->getNumberFormats());
Reference< XPropertySet> xFormat(xFormats->getByKey(getINT32(aFormatKey))); if (hasProperty(sPropCurrencySymbol, xFormat))
{
Any aVal( xFormat->getPropertyValue(sPropCurrencySymbol) ); if (aVal.hasValue() && hasProperty(sPropCurrencySymbol, xNewProps)) // If the source value hasn't been set then don't copy it // so we don't overwrite the default value
xNewProps->setPropertyValue(sPropCurrencySymbol, aVal);
} if (hasProperty(sPropDecimals, xFormat) && hasProperty(sPropDecimals, xNewProps))
xNewProps->setPropertyValue(sPropDecimals, xFormat->getPropertyValue(sPropDecimals));
}
}
// a potential Min-Max-Conversion
Any aEffectiveMin( xOldProps->getPropertyValue(sPropEffectiveMin) ); if (aEffectiveMin.hasValue())
{ // Unlike the ValueMin the EffectiveMin can be void if (hasProperty(sPropValueMin, xNewProps))
{
OSL_ENSURE(aEffectiveMin.getValueTypeClass() == TypeClass_DOUBLE, "TransferFormComponentProperties : invalid property type !");
xNewProps->setPropertyValue(sPropValueMin, aEffectiveMin);
}
}
Any aEffectiveMax( xOldProps->getPropertyValue(sPropEffectiveMax) ); if (aEffectiveMax.hasValue())
{ // analog if (hasProperty(sPropValueMax, xNewProps))
{
OSL_ENSURE(aEffectiveMax.getValueTypeClass() == TypeClass_DOUBLE, "TransferFormComponentProperties : invalid property type !");
xNewProps->setPropertyValue(sPropValueMax, aEffectiveMax);
}
}
// then we can still convert and copy the default values
Any aEffectiveDefault( xOldProps->getPropertyValue(sPropEffectiveDefault) ); if (aEffectiveDefault.hasValue())
{ bool bIsString = aEffectiveDefault.getValueTypeClass() == TypeClass_STRING;
OSL_ENSURE(bIsString || aEffectiveDefault.getValueTypeClass() == TypeClass_DOUBLE, "TransferFormComponentProperties : invalid property type !"); // The Effective-Properties should always be void or string or double...
if (hasProperty(sPropDefaultDate, xNewProps) && !bIsString)
{ // (to convert an OUString into a date will not always succeed, because it might be bound to a text-column, // but we can work with a double)
Date aDate = DBTypeConversion::toDate(getDouble(aEffectiveDefault));
xNewProps->setPropertyValue(sPropDefaultDate, Any(aDate));
}
if (hasProperty(sPropDefaultTime, xNewProps) && !bIsString)
{ // Completely analogous to time
css::util::Time aTime = DBTypeConversion::toTime(getDouble(aEffectiveDefault));
xNewProps->setPropertyValue(sPropDefaultTime, Any(aTime));
}
if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE), xNewProps) && !bIsString)
{ // Here we can simply pass the double
xNewProps->setPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE), aEffectiveDefault);
}
if (hasProperty(sPropDefaultText, xNewProps) && bIsString)
{ // and here the OUString
xNewProps->setPropertyValue(sPropDefaultText, aEffectiveDefault);
}
// nyi: The translation between doubles and OUString would offer more alternatives
}
}
// The other direction: the new Control shall be formatted if (bNewIsFormatted)
{ // first the formatting // we can't set a Supplier, so the new Set must bring one in
Reference< XNumberFormatsSupplier> xSupplier;
xNewProps->getPropertyValue(sPropFormatsSupplier) >>= xSupplier; if (xSupplier.is())
{
Reference< XNumberFormats> xFormats(xSupplier->getNumberFormats());
// Set number of decimals
sal_Int16 nDecimals = 2; if (hasProperty(sPropDecimalAccuracy, xOldProps))
xOldProps->getPropertyValue(sPropDecimalAccuracy) >>= nDecimals;
// base format (depending on the ClassId of the old Set)
sal_Int32 nBaseKey = 0; if (hasProperty(sPropClassId, xOldProps))
{
Reference< XNumberFormatTypes> xTypeList(xFormats, UNO_QUERY); if (xTypeList.is())
{
sal_Int16 nClassId = 0;
xOldProps->getPropertyValue(sPropClassId) >>= nClassId; switch (nClassId)
{ case FormComponentType::DATEFIELD :
nBaseKey = xTypeList->getStandardFormat(NumberFormat::DATE, _rLocale); break;
case FormComponentType::TIMEFIELD :
nBaseKey = xTypeList->getStandardFormat(NumberFormat::TIME, _rLocale); break;
// With this we can generate a new format ...
OUString sNewFormat = xFormats->generateFormat(nBaseKey, _rLocale, false, false, nDecimals, 0); // No thousands separator, negative numbers are not in red, no leading zeros
// ... and add at FormatsSupplier (if needed)
sal_Int32 nKey = xFormats->queryKey(sNewFormat, _rLocale, false); if (nKey == sal_Int32(-1))
{ // not added yet in my formatter ...
nKey = xFormats->addNew(sNewFormat, _rLocale);
}
// min-/max-Value
Any aNewMin, aNewMax; if (hasProperty(sPropValueMin, xOldProps))
aNewMin = xOldProps->getPropertyValue(sPropValueMin); if (hasProperty(sPropValueMax, xOldProps))
aNewMax = xOldProps->getPropertyValue(sPropValueMax);
xNewProps->setPropertyValue(sPropEffectiveMin, aNewMin);
xNewProps->setPropertyValue(sPropEffectiveMax, aNewMax);
// Default-Value
Any aNewDefault; if (hasProperty(sPropDefaultDate, xOldProps))
{
Any aDate( xOldProps->getPropertyValue(sPropDefaultDate) ); if (aDate.hasValue())
aNewDefault <<= DBTypeConversion::toDouble(*o3tl::doAccess<Date>(aDate));
}
if (hasProperty(sPropDefaultTime, xOldProps))
{
Any aTime( xOldProps->getPropertyValue(sPropDefaultTime) ); if (aTime.hasValue())
aNewDefault <<= DBTypeConversion::toDouble(*o3tl::doAccess<Time>(aTime));
}
// double or OUString will be copied directly if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE), xOldProps))
aNewDefault = xOldProps->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE)); if (hasProperty(sPropDefaultText, xOldProps))
aNewDefault = xOldProps->getPropertyValue(sPropDefaultText);
static Reference< XSingleSelectQueryComposer > getComposedRowSetStatement( const Reference< XPropertySet >& _rxRowSet, const Reference< XComponentContext >& _rxContext, constReference< XWindow >& _rxParent )
{
Reference< XSingleSelectQueryComposer > xComposer; try
{
Reference< XConnection> xConn = connectRowset( Reference< XRowSet >( _rxRowSet, UNO_QUERY ), _rxContext, _rxParent ); if ( xConn.is() ) // implies _rxRowSet.is()
{ // build the statement the row set is based on (can't use the ActiveCommand property of the set // as this reflects the status after the last execute, not the currently set properties)
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)
{
OSL_ENSURE(_xComposer.is(),"dbtools::askForParameters XSQLQueryComposer is null!");
OSL_ENSURE(_xParameters.is(),"dbtools::askForParameters XParameters is null!");
OSL_ENSURE(_xConnection.is(),"dbtools::askForParameters XConnection is null!");
OSL_ENSURE(_rxHandler.is(),"dbtools::askForParameters XInteractionHandler is null!");
// we have to set this here again because getCurrentSettingsComposer can force a setpropertyvalue
Reference<XParametersSupplier> xParameters(_xComposer, UNO_QUERY);
TParameterPositions::const_iterator aFind = aParameterNames.find(sName); if ( aFind != aParameterNames.end() )
aNewParameterSet[i] = true;
aParameterNames[sName].push_back(i+1);
} // build an interaction request // two continuations (Ok and Cancel)
rtl::Reference<OInteractionAbort> pAbort = new OInteractionAbort;
rtl::Reference<OParameterContinuation> pParams = new OParameterContinuation; // the request
ParametersRequest aRequest;
Reference<XIndexAccess> xWrappedParameters = new OParameterWrapper(std::move(aNewParameterSet),xParamsAsIndicies);
aRequest.Parameters = xWrappedParameters;
aRequest.Connection = _xConnection;
rtl::Reference<OInteractionRequest> pRequest = new OInteractionRequest(Any(aRequest)); // some knittings
pRequest->addContinuation(pAbort);
pRequest->addContinuation(pParams);
// execute the request
_rxHandler->handle(pRequest);
if (!pParams->wasSelected())
{ // canceled by the user (i.e. (s)he canceled the dialog)
RowSetVetoException e;
e.ErrorCode = ParameterInteractionCancelled; throw e;
}
// now transfer the values from the continuation object to the parameter columns
Sequence< PropertyValue > aFinalValues = pParams->getValues(); for (sal_Int32 i = 0; i < aFinalValues.getLength(); ++i)
{
Reference< XPropertySet > xParamColumn(xWrappedParameters->getByIndex(i),UNO_QUERY); if (xParamColumn.is())
{
OUString sName;
xParamColumn->getPropertyValue(PROPERTY_NAME) >>= sName;
OSL_ENSURE(sName == aFinalValues[i].Name, "::dbaui::askForParameters: inconsistent parameter names!");
// determine the field type and ...
sal_Int32 nParamType = 0;
xParamColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nParamType; // ... the scale of the parameter column
sal_Int32 nScale = 0; if (hasProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE), xParamColumn))
xParamColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE)) >>= nScale; // (the index of the parameters is one-based)
TParameterPositions::const_iterator aFind = aParameterNames.find(aFinalValues[i].Name); for(constauto& rItem : aFind->second)
{ if ( _aParametersSet.empty() || !_aParametersSet[rItem-1] )
{
_xParameters->setObjectWithInfo(rItem, aFinalValues[i].Value, nParamType, nScale);
}
}
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.