Pass Document directly to Driver for embedded databases.

Change-Id: I346a8ef07c5d695b3aa879f5c25cc4af97e25b99
Reviewed-on: https://gerrit.libreoffice.org/6627
Reviewed-by: Lionel Elie Mamane <lionel@mamane.lu>
Tested-by: Lionel Elie Mamane <lionel@mamane.lu>
This commit is contained in:
Andrzej J.R. Hunt
2013-11-10 08:34:27 +00:00
committed by Lionel Elie Mamane
parent d634d1a18a
commit a3eece5a88
3 changed files with 31 additions and 48 deletions

View File

@@ -124,6 +124,7 @@ void Connection::construct(const ::rtl::OUString& url, const Sequence< PropertyV
if (url.equals("sdbc:embedded:firebird"))
{
m_bIsEmbedded = true;
const PropertyValue* pIter = info.getConstArray();
const PropertyValue* pEnd = pIter + info.getLength();
@@ -137,6 +138,10 @@ void Connection::construct(const ::rtl::OUString& url, const Sequence< PropertyV
{
pIter->Value >>= aStorageURL;
}
else if ( pIter->Name == "Document" )
{
pIter->Value >>= m_xParentDocument;
}
}
if ( !m_xEmbeddedStorage.is() )
@@ -284,52 +289,19 @@ void Connection::construct(const ::rtl::OUString& url, const Sequence< PropertyV
// it in the .odb.
rebuildIndexes();
attachAsDocumentListener(aStorageURL);
// We need to attach as a document listener in order to be able to store
// the temporary db back into the .odb when saving
uno::Reference<XDocumentEventBroadcaster> xBroadcaster(m_xParentDocument, UNO_QUERY);
if (xBroadcaster.is())
xBroadcaster->addDocumentEventListener(this);
else
assert(false);
}
osl_atomic_decrement( &m_refCount );
}
void Connection::attachAsDocumentListener(const OUString& rStorageURL)
{
// We can't directly access the Document that is using this connection
// (since a Connection can in fact be used independently of a DB document)
// hence we need to iterate through all Frames to find our Document.
uno::Reference< frame::XDesktop2 > xFramesSupplier =
frame::Desktop::create(::comphelper::getProcessComponentContext());
uno::Reference< frame::XFrames > xFrames(xFramesSupplier->getFrames(),
uno::UNO_QUERY);
if (!xFrames.is())
return;
uno::Sequence< uno::Reference<frame::XFrame> > xFrameList =
xFrames->queryFrames( frame::FrameSearchFlag::ALL );
for (sal_Int32 i = 0; i < xFrameList.getLength(); i++)
{
uno::Reference< frame::XFrame > xf = xFrameList[i];
uno::Reference< XController > xc;
if (xf.is())
xc = xf->getController();
uno::Reference< XModel > xm;
if (xc.is())
xm = xc->getModel();
if (xm.is() && xm->getURL() == rStorageURL)
{
uno::Reference<XDocumentEventBroadcaster> xBroadcaster( xm, UNO_QUERY);
if (xBroadcaster.is())
{
xBroadcaster->addDocumentEventListener(this);
return;
}
//TODO: remove in the disposing?
}
}
assert(false); // If we have an embedded DB we must have a document
}
//----- XServiceInfo ---------------------------------------------------------
IMPLEMENT_SERVICE_INFO(Connection, "com.sun.star.sdbc.drivers.firebird.Connection",
"com.sun.star.sdbc.Connection")

View File

@@ -45,6 +45,7 @@
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/sdbc/XWarningsSupplier.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/util/XModifiable.hpp>
namespace connectivity
{
@@ -96,6 +97,17 @@ namespace connectivity
/* EMBEDDED MODE DATA */
/** Denotes that we have a .fdb stored within a .odb file. */
sal_Bool m_bIsEmbedded;
/**
* Handle for the parent DatabaseDocument. We need to notify this
* whenever any data is written to our temporary database so that
* the user is able to save this back to the .odb file.
*
* Note that this is ONLY set in embedded mode.
*/
::com::sun::star::uno::Reference< ::com::sun::star::util::XModifiable >
m_xParentDocument;
/**
* Handle for the folder within the .odb where we store our .fdb
* (Only used if m_bIsEmbedded is true).
@@ -130,12 +142,6 @@ namespace connectivity
/** Statements owned by this connection. */
OWeakRefArray m_aStatements;
/**
* If we are embedded in a .odb we need to listen to Document events
* in order to save the .fdb back into the .odb.
*/
void attachAsDocumentListener(const ::rtl::OUString& rStorageURL);
/**
* Firebird stores binary collations for indexes on Character based
* columns, these can be binary-incompatible between different icu

View File

@@ -703,12 +703,17 @@ Reference< XConnection > ODatabaseSource::buildLowLevelConnection(const OUString
if ( m_pImpl->isEmbeddedDatabase() )
{
sal_Int32 nCount = aDriverInfo.getLength();
aDriverInfo.realloc(nCount + 2 );
aDriverInfo.realloc(nCount + 3 );
aDriverInfo[nCount].Name = "URL";
aDriverInfo[nCount++].Value <<= m_pImpl->getURL();
aDriverInfo[nCount].Name = "Storage";
Reference< css::document::XDocumentSubStorageSupplier> xDocSup( m_pImpl->getDocumentSubStorageSupplier() );
aDriverInfo[nCount++].Value <<= xDocSup->getDocumentSubStorage("database",ElementModes::READWRITE);
aDriverInfo[nCount].Name = "Document";
aDriverInfo[nCount++].Value <<= getDatabaseDocument();
}
if (nAdditionalArgs)
xReturn = xManager->getConnectionWithInfo(m_pImpl->m_sConnectURL, ::comphelper::concatSequences(aUserPwd,aDriverInfo));