/* -*- 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 .
*/
Reference<XTablesSupplier> xSup(xConnection,UNO_QUERY);
OSL_ENSURE(xSup.is(),"OApplicationController::deleteTable: no XTablesSupplier!"); if ( !xSup.is() ) return;
short eResult = _bConfirm ? svtools::QUERYDELETE_YES : svtools::QUERYDELETE_ALL;
// The list of elements to delete is allowed to contain related elements: A given element may // be the ancestor or child of another element from the list. // We want to ensure that ancestors get deleted first, so we normalize the list in this respect. // #i33353# // Note that this implicitly uses std::less< OUString > a comparison operation, which // results in lexicographical order, which is exactly what we need, because "foo" is *before* // any "foo/bar" in this order.
std::set< OUString > aDeleteNames(_rList.begin(), _rList.end());
// now that we removed the element, care for all its child elements // which may also be a part of the list // #i33353#
OSL_ENSURE( aThisRound->getLength() - 1 >= 0, "OApplicationController::deleteObjects: empty name?" );
OUString sSmallestSiblingName = *aThisRound + OUStringChar( sal_Unicode( '/' + 1) );
if ( !bSuccess )
{ // okay, this object could not be deleted (or the user did not want to delete it), // but continue with the rest
aDeleteNames.erase( aThisRound );
--nObjectsLeft;
}
}
}
std::vector< OUString> aList;
getSelectionElementNames(aList);
ElementType eType = getContainer()->getElementType(); switch(eType)
{ case E_TABLE:
deleteTables(aList); break; case E_QUERY:
deleteObjects( E_QUERY, aList, true ); break; case E_FORM:
deleteObjects( E_FORM, aList, true ); break; case E_REPORT:
deleteObjects( E_REPORT, aList, true ); break; case E_NONE: break;
}
}
// DO NOT CALL with getMutex() held!! const SharedConnection& OApplicationController::ensureConnection( ::dbtools::SQLExceptionInfo* _pErrorInfo )
{
// This looks like double checked locking, but it is not, // because every access (read *or* write) to m_xDataSourceConnection // is mutexed. // See http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html // for what I'm referring to. // We cannot use the TLS (thread-local storage) solution // since support for TLS is not up to the snuff on Windows :-(
{
::osl::MutexGuard aGuard( getMutex() );
if ( m_xDataSourceConnection.is() ) return m_xDataSourceConnection;
}
// do the connection *without* holding getMutex() to avoid deadlock // when we are not in the main thread and we need username/password // (and thus to display a dialog, which will be done by the main thread) // and there is an event that needs getMutex() *before* us in the main thread's queue // See fdo#63391
conn.set( connect( getDatabaseName(), sConnectingContext, _pErrorInfo ) );
}
// the target object name (as we'll suggest it to the user)
OUString sTargetName; try
{ if ( CommandType::QUERY == nCommandType )
sTargetName = sCommand;
Reference< XPropertySet > xQuery; if (CommandType::QUERY == nCommandType)
{ // need to extract the statement and the escape processing flag from the query object bool bSuccess = false; try
{ // the concrete query
Reference< XQueryDefinitionsSupplier > xSourceQuerySup(
getDataSourceByName( sDataSourceName, getFrameWeld(), getORB(), nullptr ),
UNO_QUERY_THROW );
Reference< XNameAccess > xQueries( xSourceQuerySup->getQueryDefinitions(), UNO_SET_THROW ); if ( xQueries->hasByName( sCommand ) )
{
xQuery.set( xQueries->getByName(sCommand), UNO_QUERY_THROW );
bSuccess = true;
}
} catch(SQLException&) { throw; } // caught and handled by the outer catch catch( const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess");
}
if (!bSuccess)
{
OSL_FAIL("OApplicationController::paste: could not extract the source query object!"); // TODO: maybe this is worth an error message to be displayed to the user... returnfalse;
}
}
// here we have everything needed to create a new query object... // ... ehm, except a new name
ensureConnection();
DynamicTableOrQueryNameCheck aNameChecker( getConnection(), CommandType::QUERY );
::dbtools::SQLExceptionInfo aDummy; bool bNeedAskForName = ( sCommand.isEmpty() ) /* we did not have a source name, so the target name was auto-generated */
|| ( !aNameChecker.isNameValid( sTargetName, aDummy ) ); /* name is invalid in the target DB (e.g. because it already
has a /table/ with that name) */ if ( bNeedAskForName )
{
OSaveAsDlg aAskForName(getFrameWeld(),
CommandType::QUERY,
getORB(),
getConnection(),
sTargetName,
aNameChecker,
SADFlags::AdditionalDescription | SADFlags::TitlePasteAs ); if ( RET_OK != aAskForName.run() ) // cancelled by the user returnfalse;
sTargetName = aAskForName.getName();
}
// create a new object
Reference< XPropertySet > xNewQuery(xQueryFactory->createInstance(), UNO_QUERY);
OSL_ENSURE(xNewQuery.is(), "OApplicationController::paste: invalid object created by factory!"); if (xNewQuery.is())
{ // initialize if ( xQuery.is() )
::comphelper::copyProperties(xQuery,xNewQuery); else
{
xNewQuery->setPropertyValue(PROPERTY_COMMAND,Any(sCommand));
xNewQuery->setPropertyValue(PROPERTY_ESCAPE_PROCESSING,Any(bEscapeProcessing));
} // insert
xDestQueries->insertByName( sTargetName, Any(xNewQuery) );
xNewQuery.set(xDestQueries->getByName( sTargetName),UNO_QUERY); if ( xQuery.is() && xNewQuery.is() )
{
Reference<XColumnsSupplier> xSrcColSup(xQuery,UNO_QUERY);
Reference<XColumnsSupplier> xDstColSup(xNewQuery,UNO_QUERY); if ( xSrcColSup.is() && xDstColSup.is() )
{
Reference<XNameAccess> xSrcNameAccess = xSrcColSup->getColumns();
Reference<XNameAccess> xDstNameAccess = xDstColSup->getColumns();
Reference<XDataDescriptorFactory> xFac(xDstNameAccess,UNO_QUERY);
Reference<XAppend> xAppend(xFac,UNO_QUERY); if ( xSrcNameAccess.is() && xDstNameAccess.is() && xSrcNameAccess->hasElements() && xAppend.is() )
{
Reference<XPropertySet> xDstProp(xFac->createDataDescriptor());
for (auto& name : xSrcNameAccess->getElementNames())
{
Reference<XPropertySet> xSrcProp(xSrcNameAccess->getByName(name),UNO_QUERY);
::comphelper::copyProperties(xSrcProp,xDstProp);
xAppend->appendByDescriptor(xDstProp);
}
}
}
}
}
} else
SAL_WARN("dbaccess", "There should be a sequence in it!"); returntrue;
} elseif ( _rPasteData.has(DataAccessDescriptorProperty::Component) ) // forms or reports
{
Reference<XContent> xContent;
_rPasteData[DataAccessDescriptorProperty::Component] >>= xContent; return insertHierarchyElement(_eType,_sParentFolder,Reference<XNameAccess>(xContent,UNO_QUERY).is(),xContent,_bMove);
}
} catch(const SQLException&) { showError( SQLExceptionInfo( ::cppu::getCaughtException() ) ); } catch(const Exception& )
{
DBG_UNHANDLED_EXCEPTION("dbaccess");
} returnfalse;
}
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.