tdf#117118 - Saves data automatically in Firebird embedded database
Saves data when disposing connection regardless of
whether or not the save button is pressed. Solve Linux problems reported
after previous patch (commit 9227fbabe0a33134f56aefdd8ec16024f006a659) was reverted.
Change-Id: Idc02930c894560dfdb40265c253ee7c5557fe18b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159019
Tested-by: Jenkins
Tested-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
diff --git a/connectivity/source/drivers/firebird/Connection.cxx b/connectivity/source/drivers/firebird/Connection.cxx
index 9b1c838..5a2be88 100644
--- a/connectivity/source/drivers/firebird/Connection.cxx
+++ b/connectivity/source/drivers/firebird/Connection.cxx
@@ -339,12 +339,6 @@ void Connection::construct(const OUString& url, const Sequence< PropertyValue >&
}
}
void Connection::notifyDatabaseModified()
{
if (m_xParentDocument.is()) // Only true in embedded mode
m_xParentDocument->setModified(true);
}
//----- XServiceInfo ---------------------------------------------------------
IMPLEMENT_SERVICE_INFO(Connection, "com.sun.star.sdbc.drivers.firebird.Connection",
"com.sun.star.sdbc.Connection")
@@ -822,42 +816,9 @@ void SAL_CALL Connection::documentEventOccured( const DocumentEvent& Event )
if ( !(m_bIsEmbedded && m_xEmbeddedStorage.is()) )
return;
SAL_INFO("connectivity.firebird", "Writing .fbk from running db");
try
{
runBackupService(isc_action_svc_backup);
}
catch (const SQLException& e)
{
auto a = cppu::getCaughtException();
throw WrappedTargetRuntimeException(e.Message, e.Context, a);
}
Reference< XStream > xDBStream(m_xEmbeddedStorage->openStreamElement(our_sFBKLocation,
ElementModes::WRITE));
// TODO: verify the backup actually exists -- the backup service
// can fail without giving any sane error messages / telling us
// that it failed.
using namespace ::comphelper;
Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
Reference< XInputStream > xInputStream;
if (!xContext.is())
return;
xInputStream =
OStorageHelper::GetInputStreamFromURL(m_sFBKPath, xContext);
if (xInputStream.is())
OStorageHelper::CopyInputToOutput( xInputStream,
xDBStream->getOutputStream());
// remove old fdb file if exists
uno::Reference< ucb::XSimpleFileAccess > xFileAccess =
ucb::SimpleFileAccess::create(xContext);
if (xFileAccess->exists(m_sFirebirdURL))
xFileAccess->kill(m_sFirebirdURL);
storeDatabase();
}
// XEventListener
void SAL_CALL Connection::disposing(const EventObject& /*rSource*/)
{
@@ -938,13 +899,43 @@ void Connection::disposing()
evaluateStatusVector(status, u"isc_detach_database", *this);
}
}
// TODO: write to storage again?
storeDatabase();
cppu::WeakComponentImplHelperBase::disposing();
m_pDatabaseFileDir.reset();
}
void Connection::storeDatabase()
{
MutexGuard aGuard(m_aMutex);
if (m_bIsEmbedded && m_xEmbeddedStorage.is())
{
SAL_INFO("connectivity.firebird", "Writing .fbk from running db");
try
{
runBackupService(isc_action_svc_backup);
}
catch (const SQLException& e)
{
auto a = cppu::getCaughtException();
throw WrappedTargetRuntimeException(e.Message, e.Context, a);
}
Reference<XStream> xDBStream(
m_xEmbeddedStorage->openStreamElement(our_sFBKLocation, ElementModes::WRITE));
using namespace ::comphelper;
Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
Reference<XInputStream> xInputStream;
if (!xContext.is())
return;
xInputStream = OStorageHelper::GetInputStreamFromURL(m_sFBKPath, xContext);
if (xInputStream.is())
OStorageHelper::CopyInputToOutput(xInputStream, xDBStream->getOutputStream());
}
}
void Connection::disposeStatements()
{
MutexGuard aGuard(m_aMutex);
diff --git a/connectivity/source/drivers/firebird/Connection.hxx b/connectivity/source/drivers/firebird/Connection.hxx
index fa89643..16ac0ff 100644
--- a/connectivity/source/drivers/firebird/Connection.hxx
+++ b/connectivity/source/drivers/firebird/Connection.hxx
@@ -172,16 +172,6 @@ namespace connectivity::firebird
isc_tr_handle& getTransaction();
/**
* Must be called anytime the underlying database is likely to have
* changed.
*
* This is used to notify the database document of any changes, so
* that the user is informed of any pending changes needing to be
* saved.
*/
void notifyDatabaseModified();
/**
* Create a new Blob tied to this connection. Blobs are tied to a
* transaction and not to a statement, hence the connection should
* deal with their management.
@@ -203,6 +193,11 @@ namespace connectivity::firebird
css::uno::Reference< css::sdbcx::XTablesSupplier >
createCatalog();
/**
* Backup and store embedded extracted database to the .odb file
*/
void storeDatabase();
// OComponentHelper
virtual void SAL_CALL disposing() override;
diff --git a/connectivity/source/drivers/firebird/PreparedStatement.cxx b/connectivity/source/drivers/firebird/PreparedStatement.cxx
index 608d05c..35847d0 100644
--- a/connectivity/source/drivers/firebird/PreparedStatement.cxx
+++ b/connectivity/source/drivers/firebird/PreparedStatement.cxx
@@ -334,9 +334,6 @@ sal_Bool SAL_CALL OPreparedStatement::execute()
m_aStatementHandle,
m_pOutSqlda);
if (getStatementChangeCount() > 0)
m_pConnection->notifyDatabaseModified();
return m_xResultSet.is();
// TODO: implement handling of multiple ResultSets.
}
diff --git a/connectivity/source/drivers/firebird/Statement.cxx b/connectivity/source/drivers/firebird/Statement.cxx
index ed56b59..d135c4e 100644
--- a/connectivity/source/drivers/firebird/Statement.cxx
+++ b/connectivity/source/drivers/firebird/Statement.cxx
@@ -126,11 +126,6 @@ uno::Reference< XResultSet > SAL_CALL OStatement::executeQuery(const OUString& s
if (isDDLStatement())
{
m_pConnection->commit();
m_pConnection->notifyDatabaseModified();
}
else if (getStatementChangeCount() > 0)
{
m_pConnection->notifyDatabaseModified();
}
return m_xResultSet;